POJ 2186 Popular Cows (强连通分量)

来源:互联网 发布:中科vipexam数据库 编辑:程序博客网 时间:2024/05/16 13:02

题目地址:POJ 2186

先用强连通分量缩点,然后形成一棵树。我第一次用的判定条件是入度为分量数-1。虽然这种情况下确实正确。但是在树中也是有间接关系的。这个条件并不是充分必要条件。正确的做法是逆序建树,然后找根结点。而且根结点有且只有一个才可以。所以转化成了找出度为0的分量。

代码如下:

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <algorithm>#include <stdlib.h>#include <map>#include <set>#include <stdio.h>using namespace std;#define LL long long#define pi acos(-1.0)const int mod=1e9+7;const int INF=0x3f3f3f3f;const double eqs=1e-9;const int MAXN=10000+10;int head[MAXN], Ecnt, top, indx, scc;int low[MAXN], dfn[MAXN], belong[MAXN], instack[MAXN], stk[MAXN], out[MAXN];struct node{        int u, v, next;}edge[1000000];void add(int u, int v){        edge[Ecnt].v=v;        edge[Ecnt].next=head[u];        head[u]=Ecnt++;}void tarjan(int u){        low[u]=dfn[u]=++indx;        instack[u]=1;        stk[++top]=u;        for(int i=head[u];i!=-1;i=edge[i].next){                int v=edge[i].v;                if(!dfn[v]){                        tarjan(v);                        low[u]=min(low[u],low[v]);                }                else if(instack[v]){                        low[u]=min(low[u],dfn[v]);                }        }        if(low[u]==dfn[u]){                scc++;                while(1){                        int v=stk[top--];                        belong[v]=scc;                        instack[v]=0;                        if(u==v) break;                }        }}void init(){        memset(head,-1,sizeof(head));        memset(dfn,0,sizeof(dfn));        memset(instack,0,sizeof(instack));        memset(out,0,sizeof(out));        Ecnt=top=indx=scc=0;}int main(){        int n, m, i, j, u, v, ans, cnt;        while(scanf("%d",&n)!=EOF&&n){                scanf("%d",&m);                init();                while(m--){                        scanf("%d%d",&u,&v);                        add(u,v);                }                for(i=1;i<=n;i++){                        if(!dfn[i]) tarjan(i);                }                for(i=1;i<=n;i++){                        for(j=head[i];j!=-1;j=edge[j].next){                                v=edge[j].v;                                if(belong[i]!=belong[v]){                                        out[belong[i]]++;                                }                        }                }                ans=0;                cnt=0;                for(i=1;i<=scc;i++){                        if(!out[i]) cnt++;                }                if(cnt>1) printf("0\n");                else{                        for(i=1;i<=n;i++){                                if(out[belong[i]]==0)                                        ans++;                        }                        printf("%d\n",ans);                }        }        return 0;}


0 0
原创粉丝点击