【POJ】3180

来源:互联网 发布:wifi网络测试工具 编辑:程序博客网 时间:2024/06/06 03:10

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

N头牛,M条有向绳子,能组成几个歌舞团?要求顺时针逆时针都能带动舞团内所有牛。

即n个点,m条有向路,能构成几个强连通分量?

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <stack>#include <vector>#include <numeric>#include <algorithm>using namespace std;const int maxn=50005;int n,m;vector <int> G[maxn];vector <int> rG[maxn];vector <int> vs;bool vis[maxn];int cmp[maxn];void add(int from,int to){    G[from].push_back(to);    rG[to].push_back(from);}void dfs(int v){    vis[v]=true;    for (int i=0;i<G[v].size();i++){        if (!vis[G[v][i]]){            dfs(G[v][i]);        }    }    vs.push_back(v);}void rdfs(int v,int k){    vis[v]=true;    cmp[v]=k;    for (int i=0;i<rG[v].size();i++){        if (!vis[rG[v][i]]){            rdfs(rG[v][i],k);        }    }}int scc(){    memset(vis,false,sizeof(vis));    vs.clear();    for (int i=1;i<=n;i++){        if (!vis[i]){            dfs(i);        }    }    memset(vis,false,sizeof(vis));    int k=0;    for (int i=vs.size()-1;i>=0;i--){        if (!vis[vs[i]]){            rdfs(vs[i],k++);        }    }    return k;}int main(){    cin >> n >> m;    for (int i=0;i<m;i++){        int from,to;        scanf("%d%d",&from,&to);        add(from,to);    }    int Scc=scc();    vector <int> cnt(Scc,0);    for (int i=1;i<=n;i++){        cnt[cmp[i]]++;    }    int ans=0;    for (int i=0;i<Scc;i++){        if (cnt[i]>=2){            ans++;        }    }    cout << ans << endl;}
原创粉丝点击