poj 2186 Popular Cows

http://poj.org/problem?id=2186

题意:若A认为B好,且B又认为C好,则可以推出A认为C好,现给一个这样的无向关系图,求出有多少个点,所有人都认为它好。

思路:先对图进行tarjan去环缩边成点,并统计环中点的个数,然后查看一下出度为0的点是否为1,如果是则这个点代表的环里的点的数目,否则puts("0");

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stack>
#include<utility>
using namespace std;
const int maxn = 10005;
struct nd
{
        int u,v,next;
}edge[maxn*5];
int head[maxn],ecnt,cnt,idx;
int dfn[maxn],low[maxn],vis[maxn],belong[maxn],c[maxn],out[maxn];
stack<int>st;

void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}

void tarjan(int u)
{
        int i,v;
        dfn[u] = low[u] = ++idx;
        vis[u] = 1;
        st.push(u);
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u] = min(low[v],low[u]);
                }else if(vis[v]) low[u] = min(dfn[v],low[u]);
        }
        if(dfn[u] == low[u])
        {
                cnt++;
                do{
                        v = st.top();
                        st.pop();
                        vis[v] = 0;
                        belong[v] = cnt;
                        c[cnt]++;
                }while(v!=u);
        }
}

int main()
{
        int i,j,k,t,n,m,u,v;
        while(scanf("%d %d",&n,&m)==2)
        {
                memset(head,-1,sizeof(head));
                memset(vis,0,sizeof(vis));
                memset(dfn,0,sizeof(dfn));
                memset(low,0,sizeof(low));
                memset(c,0,sizeof(c));
                memset(belong,0,sizeof(belong));
                memset(out,0,sizeof(out));
                ecnt = 0; idx = 0; cnt = 0;
                for(i = 0; i < m; ++ i)
                {
                        scanf("%d %d",&u,&v);
                        add(u,v);
                }
                for(i = 1; i <= n; ++ i) if(!dfn[i]) tarjan(i);
                for(i = 0; i < ecnt; ++ i)
                {
                        u = belong[edge[i].u];
                        v = belong[edge[i].v];
                        if(v!=u)out[u]++;
                }
                k = 0;
                for(i = 1; i <= cnt; ++ i) if(!out[i]){k++;j=i;}
                if(k!=1)puts("0");
                else printf("%d\n",c[j]);
        }
        return 0;
}

下面代码过不了,不知道为什么?求解中~~~

View Code
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stack>
#include<utility>
using namespace std;
const int maxn = 10005;
struct nd
{
        int u,v,next;
}edge[maxn*5];
int head[maxn],ecnt,cnt,idx;
int dfn[maxn],low[maxn],vis[maxn],belong[maxn],c[maxn],in[maxn];
stack<int>st;

void add(int u,int v)
{
        edge[ecnt].u = u;
        edge[ecnt].v = v;
        edge[ecnt].next = head[u];
        head[u] = ecnt++;
}

void tarjan(int u)
{
        int i,v;
        dfn[u] = low[u] = ++idx;
        vis[u] = 1;
        st.push(u);
        for(i = head[u]; i != -1; i = edge[i].next)
        {
                v = edge[i].v;
                if(!dfn[v]){
                        tarjan(v);
                        low[u] = min(low[v],low[u]);
                }else if(vis[v]) low[u] = min(dfn[v],low[u]);
        }
        if(dfn[u] == low[u])
        {
                cnt++;
                do{
                        v = st.top();
                        st.pop();
                        vis[v] = 0;
                        belong[v] = cnt;
                        c[cnt]++;
                }while(v!=u);
        }
}
int dfs(int x)
{
        int i,j,k = 0,v;
        for(i = head[x]; i != -1; i = edge[i].next)
        {
                j = edge[i].v;
                in[j]--;
                if(!in[j]) {k++;v=j;}
                if(k>1) return 0;
        }
        if(k)return dfs(v);
        return c[x];
}
int main()
{
        int i,j,k,t,n,m,u,v;
        while(scanf("%d %d",&n,&m)==2)
        {
                memset(head,-1,sizeof(head));
                memset(vis,0,sizeof(vis));
                memset(dfn,0,sizeof(dfn));
                memset(low,0,sizeof(low));
                memset(c,0,sizeof(c));
                memset(belong,0,sizeof(belong));
                memset(in,0,sizeof(in));
                ecnt = 0; idx = 0; cnt = 0;
                for(i = 0; i < m; ++ i)
                {
                        scanf("%d %d",&u,&v);
                        if(u!=v)
                        add(u,v);
                }
                for(i = 1; i <= n; ++ i) if(!dfn[i]) tarjan(i);
                k = ecnt; ecnt = 0;
                memset(head,-1,sizeof(head));
                for(i = 0; i < k; ++ i)
                {
                        u = belong[edge[i].u];
                        v = belong[edge[i].v];
                        if(v!=u) { add(u,v); in[v]++;}
                }
                k = 0;
                for(i = 1; i <= cnt; ++ i) if(!in[i]){k++;j=i;}
                if(k!=1)puts("0");
                else printf("%d\n",dfs(j));
        }
        return 0;
}

 

 

posted on 2012-06-27 21:18  aigoruan  阅读(133)  评论(0)    收藏  举报

导航