Description
Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.
Input
* Line 1: Two space-separated integers, N and M
* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.
* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.
Output
* Line 1: A single integer that is the number of cows who are considered popular by every other cow.
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Cow 3 is the only cow of high popularity.
题意为在一个有向图中,求这样点的个数,哪样的点呢!就是任意点都能到达它,
我们可以知道,要是在一个有向无环的图中,这样的点就是出度为0的点,这样我们就要把图转化成无环的图,那就简单了,先求出强连通分量,再缩点,这样就得到了有向无环的图,就可以统计它们的出度了,若个数为0,则表明原图就是强连通图,输出n,若大于一,则没有答案,输出0,若为1,则输出那个点属于的强连通快的个数,就是答案了
#include<map> #include<set> #include<stack> #include<queue> #include<cmath> #include<vector> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define inf 0x0f0f0f0f using namespace std; int degree[10000+10]; struct SCC { static const int maxn=10000+10; vector<int>group[maxn],scc[maxn]; int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt,n,m; stack<int>S; void init() { for (int i=0;i<=n;i++) group[i].clear(); } void addedge(int from,int to) { group[from].push_back(to); } void dfs(int u) { pre[u]=lowlink[u]=++dfs_clock; S.push(u); for (int i=0;i<group[u].size();i++) { int v=group[u][i]; if (!pre[v]) { dfs(v); lowlink[u]=min(lowlink[u],lowlink[v]); } else if (!sccno[v]) { lowlink[u]=min(lowlink[u],pre[v]); } } if (lowlink[u]==pre[u]) { scc_cnt++; scc[scc_cnt].clear(); while (1) { int x=S.top(); S.pop(); scc[scc_cnt].push_back(x); sccno[x]=scc_cnt; if (x==u) break; } } } void find_scc() { dfs_clock=scc_cnt=0; memset(pre,0,sizeof(pre)); memset(sccno,0,sizeof(sccno)); for (int i=1;i<=n;i++) if (!pre[i]) dfs(i); } }; SCC cow; int main() { int x,y,id; while (scanf("%d%d",&cow.n,&cow.m)!=EOF) { cow.init(); for (int i=1;i<=cow.m;i++) { scanf("%d%d",&x,&y); cow.addedge(x,y); } cow.find_scc(); for (int i=1;i<=cow.scc_cnt;i++) degree[i]=0; for (int u=1;u<=cow.n;u++) for (int i=0;i<cow.group[u].size();i++) { int v=cow.group[u][i]; if (cow.sccno[u] != cow.sccno[v]) degree[cow.sccno[u]]++; } int ans=0; for (int i=1;i<=cow.scc_cnt;i++) if (degree[i]==0) {ans++; id=i;} if (ans==0) printf("%d ",cow.n); else if (ans==1) printf("%d ",cow.scc[id].size()); else printf("0 "); } return 0; }