| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 28379 | Accepted: 11488 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
题意:A认为B受欢迎,B认为C受欢迎,那么A就认为C受欢迎。给定N头牛,M个认为受欢迎情况。确定受所有牛欢迎的这些牛的数目。
思路:首先判断有向图是否连通,若不连通则答案为0。若连通则进行缩点(注意有向图与无向图的缩点的不同之处),缩点之后得到一个有向树。若树中存在多个叶子结点,则答案为0,否则答案为 缩成叶子结点的那个连通分量重结点的数目。
#include"cstdio" #include"cstring" #include"vector" using namespace std; const int MAXN=10005; int V,E; vector<int> G[MAXN]; vector<int> rG[MAXN]; int vis[MAXN]; int deg[MAXN]; int pos; void dfs(int u) { vis[u]=1; pos=u; for(int i=0;i<G[u].size();i++) { int to=G[u][i]; if(!vis[to]) { dfs(to); } } } void rdfs(int u) { vis[u]=1; for(int i=0;i<rG[u].size();i++) { int to=rG[u][i]; if(!vis[to]) { rdfs(to); } } } bool pass() { memset(vis,0,sizeof(vis)); dfs(1); memset(vis,0,sizeof(vis)); rdfs(pos); for(int i=1;i<=V;i++) if(!vis[i]) return false; return true; } int index; int dfn[MAXN],low[MAXN]; int stack[MAXN],top; int cpnt[MAXN],cnt; inline int min(int a,int b) { return a > b? b: a; } void tarjan(int u,int fa) { stack[top++]=u; dfn[u]=low[u]=++index; for(int i=0;i<G[u].size();i++) { int to=G[u][i]; if(!dfn[to]) { tarjan(to,u); low[u]=min(low[u],low[to]); } else low[u]=min(low[u],dfn[to]);//注意有向图与无向图缩点的不同 } if(dfn[u]==low[u]) { int v; ++cnt; do{ v=stack[--top]; cpnt[v]=cnt; }while(u!=v); } } int seek() { for(int i=1;i<=V;i++) for(int j=0;j<G[i].size();j++) { int to=G[i][j]; if(cpnt[i]!=cpnt[to]) { deg[cpnt[i]]++; } } int v; int flag=0; for(int i=1;i<=cnt;i++) if(deg[i]==0)//答案肯定为叶子结点 { v=i; flag++; } if(flag>1) return 0;//必须只存在一个叶子结点 int ans=0; for(int i=1;i<=V;i++) if(cpnt[i]==v) ans++; return ans; } int main() { while(scanf("%d%d",&V,&E)!=EOF) { for(int i=1;i<=V;i++) { G[i].clear(); rG[i].clear(); } for(int i=0;i<E;i++) { int u,v; scanf("%d%d",&u,&v); G[u].push_back(v); rG[v].push_back(u); } if(pass()) { index=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); top=0; cnt=0; memset(cpnt,0,sizeof(cpnt)); tarjan(1,-1); memset(deg,0,sizeof(deg)); int ans=seek(); printf("%d\n",ans); } else { printf("0\n"); } } return 0; }
原文:http://www.cnblogs.com/program-ccc/p/5167845.html