POJ 2762 判断无向图的弱连通
来源:互联网 发布:网络在线记账 编辑:程序博客网 时间:2024/05/29 12:49
Going from u to v or from v to u?
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 16859 Accepted: 4502
Description
In order to make their sons brave, Jiajia and Wind take them to a big cave. The cave has n rooms, and one-way corridors connecting some rooms. Each time, Wind choose two rooms x and y, and ask one of their little sons go from one to the other. The son can either go from x to y, or from y to x. Wind promised that her tasks are all possible, but she actually doesn't know how to decide if a task is possible. To make her life easier, Jiajia decided to choose a cave in which every pair of rooms is a possible task. Given a cave, can you tell Jiajia whether Wind can randomly choose two rooms without worrying about anything?
Input
The first line contains a single integer T, the number of test cases. And followed T cases.
The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.
The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.
Output
The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.
Sample Input
13 31 22 33 1
Sample Output
Yes
Source
POJ Monthly--2006.02.26,zgl & twb
意:给出n个山洞,对于每个山洞,如果任意选择两点s,e,都满足s可以到达e或者e可以到达s,则输出Yes,否则输出No。
分析:实际上判断是否弱连通,所以首先强连通,然后缩点,对缩点形成的图最多只能有一个入度为0的点,如果有多个入度为
0的点,则这两个连通分量肯定是不连通的。缩点后形成的图形是一棵树,入度为0的点是这颗树的根,这棵树只能是单链,不
能有分叉,如果有分叉,则这些分叉之间是不可达的,所以就对这棵树进行DFS,如果是单链则是YES。
#include <iostream>#include <string.h>#include <stdio.h>using namespace std;const int N = 10005;struct Edge{ int to; Edge *next;};Edge *map1[N],*map2[N]; //分别保存原图和缩点后的图int dfn[N],low[N],stack[N],belong[N],indeg[N];int index,scc_num,top;bool tmp[N];int result[N];void Tarjan(int u){ dfn[u] = low[u] = ++index; stack[++top] = u; tmp[u] = true; for(Edge *p = map1[u]; p; p = p->next) //枚举每一条边 { int v = p->to; if(!dfn[v]) { Tarjan(v); //dfs继续下找 low[u] = min(low[u],low[v]); } else if(tmp[v]) { low[u] = min(low[u],dfn[v]); } } if(low[u] == dfn[u]) //如果节点u是强连通分量的根 { int t; ++scc_num; //强连通分量个数加1 do { t = stack[top--]; tmp[t] = false; belong[t] = scc_num; //记录属于第几个强连通分量 } while(t != u); }}int Count(int n){ for(int i=1; i<=n; i++) if(!dfn[i]) Tarjan(i); return scc_num;}int Find() //在新图中找入度为0的点,如果只有一个就返回位置,否则返回0{ int record; int cnt = 0; for(int i=1; i<=scc_num; i++) { if(indeg[i] == 0) { cnt++; record = i; } } if(cnt == 1) return record; return 0;}bool TopSort(){ int u,num = 0; while(u = Find()) { result[num++] = u; indeg[u] = -1; Edge *p = map2[u]; while(p) { indeg[p->to]--; p = p->next; } } if(num == scc_num) return true; return false;}void Init(){ index = 0; top = 0; scc_num = 0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(indeg,0,sizeof(indeg)); memset(tmp,false,sizeof(tmp)); memset(map1,NULL,sizeof(map1)); memset(map2,NULL,sizeof(map2)); memset(result,0,sizeof(result));}int main(){ int T,m,n; scanf("%d",&T); while(T--) { Init(); scanf("%d%d",&n,&m); while(m--) { int a,b; scanf("%d%d",&a,&b); Edge *p = new Edge(); p->to = b; p->next = map1[a]; map1[a] = p; } int cnt = Count(n); if(cnt == 1) { puts("Yes"); continue; } for(int i=1; i<=n; i++) { Edge *p = map1[i]; while(p) { if(belong[i] != belong[p->to]) { indeg[belong[p->to]]++; Edge *q = new Edge(); q->to = belong[p->to]; q->next = map2[belong[i]]; map2[belong[i]] = q; } p = p->next; } } bool flag = false; int ans = 0; for(int i=1; i<=cnt; i++) { if(indeg[i] == 0) ans++; } if(ans > 1) flag = false; else if(TopSort()) flag = true; if(flag) puts("Yes"); else puts("No"); } return 0;}
0 0
- POJ 2762 判断无向图的弱连通
- POJ2762(判断无向图的弱连通)
- poj 3713(判断无向图是否三连通)
- 判断无向图是不是连通的c++代码
- poj 1966 无向图的点连通度
- 判断无向图G是否连通
- 无向图的连通子图
- 求解无向连通图的关节点
- 无向图的连通分量
- 无向图的连通分支
- 无向图的连通分量
- 无向图的连通分支
- 无向图的连通分量
- 求无向图的连通分量
- 无向图的连通分量
- 无向图连通判断(并查集)
- 数据结构判断无向图是否为连通
- 使用并查集判断无向图是否连通
- 操作系统常见面试题总结
- 板级信息
- 牛刀小试(一)
- 排序之归并排序
- C语言 指针与一维数组,指针遍历一维数组的多种方法
- POJ 2762 判断无向图的弱连通
- 信号量和PV操作
- Java基本数据类型包装类转换小记
- 字符串
- Thread中start()和run()的区别
- unity-unet-自定义可视化区域范围(NetworkProximityChecker)
- ubuntu下使用SVN
- 最长锯齿序列 Leetcode
- ACM rightmost digit