这道题求被其他牛欢迎的牛的个数。原图是一个有向图,将其缩点后,每一个强连通分量是
一个点,找出出度为1的点的个数,如果大于1,那么无解。如果等于1,则输出这个强连通
分量中点的个数。
/*Accepted 736K 110MS C++ 1999B 2012-07-30 11:49:48*/ #include<cstdio> #include<cstring> #include<cstdlib> const int MAXN = 10010; const int MAXM = 50050; int first[MAXN], next[MAXM], v[MAXM], cnt, top, col, e, N, M, ans; int dfn[MAXN], color[MAXN], s[MAXN], ins[MAXN], low[MAXN], outdgr[MAXN]; void tarjan(int cur) { int i; dfn[cur] = low[cur] = ++ cnt; s[top ++] = cur, ins[cur] = 1; for(i = first[cur]; i != -1; i = next[i]) { if(!dfn[v[i]]) { tarjan(v[i]); if(low[v[i]] < low[cur]) low[cur] = low[v[i]]; } else if(dfn[v[i]] < low[cur] && ins[v[i]]) low[cur] = dfn[v[i]]; } if(low[cur] == dfn[cur]) { ++ col; for(s[top] = -1; s[top] != cur; ) { color[s[-- top]] = col, ins[s[top]] = 0; } } } void cal() { int i, j, zeroout = 0; col = cnt = top = 0; memset(dfn, 0, sizeof dfn); memset(ins, 0, sizeof ins); memset(outdgr, 0, sizeof outdgr); for(i = 1; i <= N; i ++) if(!dfn[i]) tarjan(i); for(i = 1; i <= N; i ++) for(j = first[i]; j != -1; j = next[j]) if(color[i] != color[v[j]]) ++ outdgr[color[i]]; for(i = 1; i <= col; i ++) { if(outdgr[i] == 0) { zeroout ++; j = i; } } ans = 0; if(zeroout > 1) return; else{ for(i = 1; i <= N; i ++) { if(color[i] == j) ans ++; } } } void addedge(int x, int y) { v[e] = y; next[e] = first[x], first[x] = e ++; } void ReadGraph() { int i, x, y; e = 0; memset(first, -1, sizeof first); while(M --) { scanf("%d%d", &x, &y); addedge(x, y); } } int main() { while(scanf("%d%d", &N, &M) == 2) { ReadGraph(); cal(); printf("%d\n", ans); } return 0; }