標籤:
題目連結: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 0xfffffffusing 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 { low[u]=min(low[u], dfn[v]); } } if(low[u]==dfn[u]) { ++nBlock; do { v=Stack[--top]; 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\n"); continue; } int ans=0; for(int i=1; i<=n; i++) { if(Block[i]==Index) ans++; } printf("%d\n", ans); } return 0;}View Code
Popular Cows---poj2186(縮點,強聯通)