题目链接:http://poj.org/problem?id=2186
求有多少个点满足其他n-1个点都能到达这个点,是单向图;
所以我们可以把图进行缩点,之后求出度为0的那个点内包含的点的个数就是求得答案;
如果出度为0的不止一个,那么答案为0;
#include<cstdio> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #define N 10010 #define Lson r*2 #define Rson r*2+1 #define INF 0xfffffff using namespace std; int Stack[N], top, Out[N], Time, flag; int nBlock, Block[N], dfn[N], low[N], Is[N], n, Head[N], cnt; struct Edge { int v, next; }e[N*N]; void Init() { nBlock = cnt = top = Time = flag = 0; memset(Head, -1, sizeof(Head)); memset(low, 0, sizeof(low)); memset(dfn, 0, sizeof(dfn)); memset(Block, 0, sizeof(Block)); memset(Out, 0, sizeof(Out)); memset(Is, 0, sizeof(Is)); memset(Stack, 0, sizeof(Stack)); } void Add(int u, int v) { e[cnt].v=v; e[cnt].next=Head[u]; Head[u]=cnt++; } void Tajar(int u) { dfn[u]=low[u]=++Time; Is[u]=1; Stack[top++]=u; int v; for(int i=Head[u]; i!=-1; i=e[i].next) { v=e[i].v; if(!dfn[v]) { Tajar(v); low[u]=min(low[u], low[v]); } else if(Is[v]) { low[u]=min(low[u], dfn[v]); } } if(low[u]==dfn[u]) { ++nBlock; do { v=Stack[--top]; Is[v] = 0; Block[v]=nBlock; }while(u!=v); } } int main() { int u, v, m; while(scanf("%d%d", &n, &m)!=EOF) { Init(); for(int i=0; i<m; i++) { scanf("%d%d", &u, &v); Add(u,v); } for(int i=1; i<=n; i++) if(!low[i]) { Tajar(i); } for(int i=1; i<=n; i++) { for(int j=Head[i]; j!=-1; j=e[j].next) { u=Block[i]; v=Block[e[j].v]; if(u!=v) Out[u]++; } } flag=0; int Index; for(int i=1; i<=nBlock; i++) { if(Out[i]==0) { flag++; Index=i; } } if(flag>1) { printf("0 "); continue; } int ans=0; for(int i=1; i<=n; i++) { if(Block[i]==Index) ans++; } printf("%d ", ans); } return 0; }