poj 2186 Popular Cows

来源:互联网 发布:galgame机翻软件 编辑:程序博客网 时间:2024/06/05 16:16

人生的第一个强连通的题诞生了~


强联通缩点的理论基础感觉其实就一句话:图上的强连通是一个等价关系

(如果不知道什么是等价关系的最好去看一下关系理论。


再然后就是代码实现了。tarjan真乃神人也


缩点什么的。。


要不看看代码?


这个题是求有向图中对所有点都可达的点的个数


某结论是:DAG中当且仅当图中只有一个出度为0的时候才有被所有点可达的点,并且就是这个出度为0的点

然后显然缩点之后的图是一个DAG,那么只要找到这一个强连通分量就好了嗯



--------------------------------我是代码的分割线---------------------------------------

#include<cstdio>#include<vector>#include<stack>#include<algorithm>#include<cstring>using namespace std;const int maxn = 11234;vector<int> edge[maxn];stack<int> S;#define iter vector<int>::iteratorint dfn[maxn],low[maxn],_cnt;int bel[maxn];void init(int n){    for(int i=0;i<n;i++){        edge[i].clear();    }    while(S.empty()==false)        S.pop();    memset(dfn,-1,sizeof(dfn));    memset(low,-1,sizeof(low));    _cnt = 1;}void dfs(int st){    S.push(st);    dfn[st] = low[st] = _cnt++;    for(iter it = edge[st].begin();it!=edge[st].end();it++){        int x = *it;        if(dfn[x] == -1){            dfs(x);            low[st] = min(low[st],low[x]);        }        else if(bel[x] == -1){            low[st] = min(low[st],dfn[x]);        }    }    if(low[st] == dfn[st]){        while(S.top()!=st){            bel[S.top()] = st;            S.pop();        }        bel[st] = st;        S.pop();    }}int outd[maxn];int cal(int n){    memset(outd,0,sizeof(outd));    for(int i=1;i<=n;i++){        for(iter it = edge[i].begin();it!=edge[i].end();it++){            int x = *it;            if(bel[x] != bel[i])                outd[bel[i]]++;        }    }    int p = 0;    for(int i=1;i<=n;i++){        if(outd[bel[i]] == 0){            if(p == 0)                p = bel[i];            else if(p!=-1){                if(p != bel[i])                    p = -1;            }        }    }    if( p == 0 || p==-1)        return 0;    int ans = 0;    for(int i=1;i<=n;i++){        if(bel[i] == p)            ans++;    }    return ans;}void out(char *p,int *s,int n){    printf("%s\t",p);    for(int i=1;i<=n;i++)        printf(i<n?"%d ":"%d\n",s[i]);}#define debug(a,b) out(#a,a,b)int main(){    int n,m;    while(~scanf("%d %d",&n,&m)){        init(n);        int x,y;        while(m--){            scanf("%d %d",&x,&y);            edge[x].push_back(y);        }        for(int i=1;i<=n;i++)            if(dfn[i] == -1)                dfs(i);//        debug(dfn,n);//        debug(low,n);//        debug(bel,n);        printf("%d\n",cal(n));//        debug(outd,n);    }    return 0;}

0 0
原创粉丝点击