POJ 2186 Popular Cows 强连通分量 难度:2

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

注意是从起点往后搜索的,另外两集相交得到的就是拓扑序

#include <cstdio>
#include <cstring>
#include <vector>
#include <assert.h>
using namespace std;
const int  maxn=10010;
const int maxm=50010;
int n,m;
vector <int >G[maxn],rG[maxn],rs;
int cmp[maxn];
bool used[maxn];
void dfs(int s){
    used[s]=true;
    for(int j=0;j<G[s].size();j++){
        if(!used[G[s][j]])dfs(G[s][j]);
    }
    rs.push_back(s);
}
void rdfs(int s,int k){
    used[s]=true;
    cmp[s]=k;
    for(int i=0;i<rG[s].size();i++){
        int t=rG[s][i];
        if(!used[t])rdfs(t,k);
    }
}
int scc(){
    for(int i=1;i<=n;i++){
        if(!used[i])dfs(i);
    }
    memset(used,0,sizeof(used));
    int num=0;
    assert(rs.size()>0);
    for(int i=rs.size()-1;i>=0;i--){
        if(!used[rs[i]])rdfs(rs[i],++num);
    }
    return num;
}
int main(){
    scanf("%d%d",&n,&m);
    if(n==0){printf("0\n");return 0;}
    for(int i=0;i<m;i++){
        int f,t;
        scanf("%d%d",&f,&t);
        G[f].push_back(t);
        rG[t].push_back(f);
    }
    int num=scc();
    if(num==0){printf("0\n");return 0;}
    int ans=0,v;
    for(int i=1;i<=n;i++){
        if(cmp[i]==num){
            ans++;
            v=i;
        }
    }
    memset(used,0,sizeof(used));
    rdfs(v,0);
    for(int i=1;i<=n;i++){
        if(!used[i]){
            printf("0\n");return 0;
        }
    }
    printf("%d\n",ans);
    return 0;
}

  

posted @ 2014-08-15 17:32  雪溯  阅读(109)  评论(0)    收藏  举报