Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
题意:求所有牛都仰慕的牛。
思路:由题意可知都仰慕的牛在缩点后肯定是出度为0的点。故……Tarjan缩点后求出度为0的点即可。
但是如果有两个以上的点出度都为0,那么就没有都被所有牛都仰慕的牛了,因为如果有两个以上的点出度为0,那么图中这两个点肯定连不起来,即无边,就不存在了!
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <list> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define sca(a) scanf("%d",&a) #define pri(a) printf("%d\n",a) #define MM 10002 #define MN 10005 #define INF 168430090 using namespace std; typedef long long ll; int n,m,cnt,tem,Count,DFN[MN],LOW[MN],od[MN],vis[MN],suo[MN],q2[MN]; vector<int>q[MN],p[MN]; void tarjan(int u) { int j,v; DFN[u]=LOW[u]=++cnt; vis[u]=1; q2[++tem]=u; for(j=0; j<q[u].size(); j++) { v=q[u][j]; if(!DFN[v]) { tarjan(v); LOW[u]=min(LOW[u],LOW[v]); } else if(vis[v]&&DFN[v]<LOW[u]) LOW[u]=DFN[v]; } if(DFN[u]==LOW[u]) { Count++; do { v=q2[tem--]; vis[v]=0; p[Count].push_back(v); suo[v]=Count; } while(v!=u); } } void solve() { int v,i,j; Count=cnt=tem=0; mem(DFN,0); for(i=1; i<=n; i++) if(!DFN[i]) tarjan(i); for(i=1; i<=n; i++) for(j=0; j<q[i].size(); j++) { v=q[i][j]; if(suo[v]!=suo[i]) od[suo[i]]++; } } int main() { while(cin>>n>>m) { int i,j,u,v,sum=0; for(i=0; i<=n; i++) q[i].clear(),p[i].clear(); mem(od,0); mem(LOW,0); mem(vis,0); mem(suo,0); for(i=0; i<m; i++) { scanf("%d%d",&u,&v); q[u].push_back(v); } solve(); for(i=1; i<=Count; i++) if(od[i]==0) sum++,j=i; if(sum==1) cout<<p[j].size()<<endl; else cout<<0<<endl; //若存在两个点以上出度都为0,则无牛 } return 0; }