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;
}

浙公网安备 33010602011771号