pku 2762 Going from u to v or from v to u?
2011-08-01 17:12
351 查看
强联通+拓扑排序判断~~
题目大意:给定一个有向图,问该图是不是半连通图.
所谓半连通图即是指 在连通图中任意给出两个点a,b,要保证至少存在一条从a到b,或者从b到a的边。
解题思路:先用强联通进行缩点,之后再重新建图,再用拓扑排序进行判断:当某一时刻存在两个或两个以上入度为0的点则输出No,否则输出Yes!
为了学习双联通不得不学习了tarjan,先用tarjan把这个题给A了。之后不太过瘾,又用Kosaraju给A了下,结果发现Kosaraju要比tarjan更快。。很神奇。。
可能是因为我写的tarjan太丑陋了!! 或者是我写的Kosaraju更风骚一点。。 ^_^。。 不过我感觉还是后者比较容易理解一点,我写的也比较清晰!!
分别贴下两种方法的代码:
tarjan:
View Code
题目大意:给定一个有向图,问该图是不是半连通图.
所谓半连通图即是指 在连通图中任意给出两个点a,b,要保证至少存在一条从a到b,或者从b到a的边。
解题思路:先用强联通进行缩点,之后再重新建图,再用拓扑排序进行判断:当某一时刻存在两个或两个以上入度为0的点则输出No,否则输出Yes!
为了学习双联通不得不学习了tarjan,先用tarjan把这个题给A了。之后不太过瘾,又用Kosaraju给A了下,结果发现Kosaraju要比tarjan更快。。很神奇。。
可能是因为我写的tarjan太丑陋了!! 或者是我写的Kosaraju更风骚一点。。 ^_^。。 不过我感觉还是后者比较容易理解一点,我写的也比较清晰!!
分别贴下两种方法的代码:
tarjan:
View Code
# include<stdio.h> # include<string.h> # define N 1005 # define M 6005 struct node{ int from,to,next; }edge1[M],edge2[M],edge[M]; int head1 ,visit1 ,visit2 ,head2 ,T ,Belong ,head ,degree ; int tol1,tol2,tol,Tcnt,Bcnt,n,m; void add1(int a,int b) { edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++; edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++; } void add(int a,int b) { edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++; } void dfs1(int i) { int j,u; visit1[i]=1; for(j=head1[i];j!=-1;j=edge1[j].next) { u=edge1[j].to; if(!visit1[u]) dfs1(u); } T[Tcnt++]=i; } void dfs2(int i) { int j,u; visit2[i]=1; Belong[i]=Bcnt; for(j=head2[i];j!=-1;j=edge2[j].next) { u=edge2[j].to; if(!visit2[u]) dfs2(u); } } int main() { int i,j,ncase,count,index,a,b; scanf("%d",&ncase); while(ncase--) { scanf("%d%d",&n,&m); tol1=tol2=0; Bcnt=Tcnt=0; memset(head1,-1,sizeof(head1)); memset(head2,-1,sizeof(head2)); memset(visit1,0,sizeof(visit1)); memset(visit2,0,sizeof(visit2)); for(i=1;i<=m;i++) { scanf("%d%d",&a,&b); add1(a,b); } for(i=1;i<=n;i++) if(!visit1[i]) dfs1(i); for(i=Tcnt-1;i>=0;i--) { if(!visit2[T[i]]) { dfs2(T[i]); Bcnt++; } } memset(head,-1,sizeof(head)); memset(degree,0,sizeof(degree)); tol=0; for(i=0;i<tol1;i++) { a=edge1[i].from; b=edge1[i].to; if(Belong[a]!=Belong[b]) { add(Belong[a],Belong[b]); degree[Belong[b]]++; } } count=0; for(i=0;i<Bcnt;i++) { if(degree[i]==0) { count++; index=i; } } if(count>1) {printf("No\n");continue;} while(1) { count=0; for(j=head[index];j!=-1;j=edge[j].next) { i=edge[j].to; degree[i]--; if(degree[i]==0) { count++; index=i; } } if(count>1) {printf("No\n");break;} else if(count==0) {printf("Yes\n");break;} } } return 0; }
相关文章推荐
- PKU 2762 Going from u to v or from v to u? - 单连通图判定
- PKU2762 Going from u to v or from v to u 【强连通
- pku2762(Going from u to v or from v to u?)
- poj 2762 Going from u to v or from v to u
- POJ2762 Going from u to v or from v to u?(强连通缩点+拓扑排序)
- poj 2762 Going from u to v or from v to u? 强连通最长链
- POJ 2762 Going from u to v or from v to u?(Tarjan + 拓扑排序)
- poj2762 Going from u to v or from v to u?(强联通+拓扑排序)
- poj 2762 Going from u to v or from v to u?
- POJ 2762 Going from u to v or from v to u? 强连通+判断链
- [POJ 2762]Going from u to v or from v to u? (强连通分量+拓扑排序)
- poj-2762-Going from u to v or from v to u?-tarjan算法求缩点+算是不是一字链
- poj 2762 Going from u to v or v to u (tarjan+缩点+dfs搜索)
- Going from u to v or from v to u? - POJ 2762 Tarjan+拓扑排序
- poj 2762 Going from u to v or from v to u? 强连通最长链
- POJ 2762 Going from u to v or from v to u? Tarjan缩点+判断链
- POJ 2762 Going from u to v or from v to u?(强连通+拓扑)
- poj2762 Going from u to v or from v to u? 有向图 强连通分量 拓扑排序
- poj2762 Going from u to v or from v to u?
- POJ 2762 Going from u to v or from v to u? / 强连通分量&&拓扑