[POJ2186]Popular Cows
思路:
Tarjan+缩点。
最受欢迎的牛一定在出度为$0$的那个连通分量中,注意有可能整个图不是一个连通图,因此我们要判断出度为$0$的连通分量是否只有一个,如果不是,说明无解,直接输出$0$。
1 #include<stack> 2 #include<cstdio> 3 #include<cctype> 4 #include<vector> 5 #include<cstring> 6 inline int getint() { 7 char ch; 8 while(!isdigit(ch=getchar())); 9 int x=ch^'0'; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 11 return x; 12 } 13 const int V=10001; 14 std::vector<int> e[V]; 15 inline void add_edge(const int u,const int v) { 16 e[u].push_back(v); 17 } 18 std::stack<int> s; 19 int dfn[V]={0},low[V]={0},scc[V]={0},cnt=0,id=0; 20 bool ins[V]; 21 void Tarjan(const int x) { 22 dfn[x]=low[x]=++cnt; 23 s.push(x); 24 ins[x]=true; 25 for(unsigned i=0;i<e[x].size();i++) { 26 int &y=e[x][i]; 27 if(!dfn[y]) { 28 Tarjan(y); 29 low[x]=std::min(low[x],low[y]); 30 } 31 else if(ins[y]) { 32 low[x]=std::min(low[x],dfn[y]); 33 } 34 } 35 if(dfn[x]==low[x]) { 36 id++; 37 int y=x; 38 do { 39 y=s.top(); 40 s.pop(); 41 ins[y]=false; 42 scc[y]=id; 43 } while(y!=x); 44 } 45 } 46 int out[V]={0}; 47 int main() { 48 int n=getint(),m=getint(); 49 for(int i=1;i<=m;i++) { 50 int u=getint(),v=getint(); 51 add_edge(u,v); 52 } 53 for(int i=1;i<=n;i++) { 54 if(!dfn[i]) Tarjan(i); 55 } 56 for(int x=1;x<=n;x++) { 57 for(unsigned i=0;i<e[x].size();i++) { 58 int y=e[x][i]; 59 if(scc[x]!=scc[y]) out[scc[x]]++; 60 } 61 } 62 int cnt=0,ans=0; 63 for(int i=1;i<=id;i++) { 64 if(!out[i]) { 65 cnt++; 66 for(int j=1;j<=n;j++) { 67 if(scc[j]==i) ans++; 68 } 69 } 70 } 71 if(cnt==1) { 72 printf("%d\n",ans); 73 } 74 else { 75 puts("0"); 76 } 77 return 0; 78 }