题意:判断给定的有向图是否满足 1.强连通 2 每一条边属于且仅属于一个环
如果出现环,记录环上的每条边的out[]++
如果有out[]大于1的,说明有边出现在两个环上
#include<stdio.h> #include<string.h> #include<stack> #include<vector> using namespace std; #define N 20010 vector<int>map[N]; int n,ok,dfn[N],fa[N],ins[N],low[N],out[N]; int ans,idx; stack<int>Q; void judge(int v,int u) { while(u!=v) { out[u]++; if(out[u]>1){ok=0;return ;} u=fa[u]; } } void Tarjan(int u) { int v,j; dfn[u]=low[u]=idx++; Q.push(u); ins[u]=1; for(j=0;j<map[u].size();j++) { v=map[u][j]; if(dfn[v]==-1) { fa[v]=u; Tarjan(v); low[u]=low[u]>low[v]?low[v]:low[u]; } else if(ins[v]==1) { low[u]=low[u]>dfn[v]?dfn[v]:low[u]; judge(v,u);//如果v已加入在Q,记录out[]的值 } if(ok==0) return; } if(low[u]==dfn[u]) { ans++; if(ans>1){ok=0;return ;} while(1) { v=Q.top(); Q.pop(); ins[v]=0; if(v==u)break; } } } int main() { int i,j,t,x,y; scanf("%d",&t); while(t--) { scanf("%d",&n); while(scanf("%d%d",&x,&y),x+y!=0) map[x].push_back(y); memset(out,0,sizeof(out)); memset(dfn,-1,sizeof(dfn)); memset(ins,0,sizeof(ins)); ans=idx=0;ok=1; for(i=0;i<n;i++) { if(dfn[i]==-1) Tarjan(i); if(ok==0)break; } if(ok==0) printf("NO\n"); else printf("YES\n"); for(i=0;i<n;i++) map[i].clear(); } return 0; }
作者:aixiaoling1314 发表于2013-5-4 20:25:26 原文链接
阅读:26 评论:0 查看评论