poj 2762 Going from u to v or from v to u?(强连通分量+缩点重构图+拓扑排序)
2013-08-11 20:23
483 查看
http://poj.org/problem?id=2762
Going from u to v or from v to u?
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.
Output
The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.
Sample Input
Sample Output
Source
POJ Monthly--2006.02.26,zgl & twb
【题解】:
这题题目大概意思就是说 判断两个点之间是不是能够走通,u到v 或者 v到u 都行,这题开始题目意思都理解错了,一开始以为就是一个判断强连通的题;
先求强连通分量;
然后将强连通分量缩点,重构图;
强连通分量内部的点肯定是可以两两到的,所以可以不用管了;
缩点后的图,然后进行拓扑排序,如果有两个及以上的点的入度为0,那么他们之间肯定是不可达的,所以不符合
如图:
![](http://images.cnitblog.com/blog/438162/201308/11202253-4aad00a3a07b43bab8875b525cbf9a16.jpg)
【code】:
Going from u to v or from v to u?
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 12733 | Accepted: 3286 |
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.
Output
The output should contain T lines. Write 'Yes' if the cave has the property stated above, or 'No' otherwise.
Sample Input
1 3 3 1 2 2 3 3 1
Sample Output
Yes
Source
POJ Monthly--2006.02.26,zgl & twb
【题解】:
这题题目大概意思就是说 判断两个点之间是不是能够走通,u到v 或者 v到u 都行,这题开始题目意思都理解错了,一开始以为就是一个判断强连通的题;
先求强连通分量;
然后将强连通分量缩点,重构图;
强连通分量内部的点肯定是可以两两到的,所以可以不用管了;
缩点后的图,然后进行拓扑排序,如果有两个及以上的点的入度为0,那么他们之间肯定是不可达的,所以不符合
如图:
![](http://images.cnitblog.com/blog/438162/201308/11202253-4aad00a3a07b43bab8875b525cbf9a16.jpg)
【code】:
/** Judge Status:Accepted Memory:4896K Time:485MS Language:G++ Code Lenght:2940B Author:cj */ #include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<vector> #include<stack> using namespace std; #define N 1010 #define M 6060 struct Edge { int v; int next; int u; }edge[M]; //M 开始传的N RE int head ,edge_cnt;//这一行变量是构造边的 int pre ,lowlink ,sccno ,dfs_cnt,scc_cnt; //这两行是Tarjan算法求强连通分量用的 stack<int> stk; vector<int> G ; //缩点重构图用的邻接链表 int in ,mark ; //入度统计,以及重复边的标记 void init() { memset(head,-1,sizeof(head)); edge_cnt = 0; } void addEdge(int a,int b) { edge[edge_cnt].v = b; edge[edge_cnt].next = head[a]; edge[edge_cnt].u = a; //这里记录a,重构图用,方便遍历所有边 head[a] = edge_cnt++; } void Tarjan(int u) //强连通分量 { stk.push(u); pre[u] = lowlink[u] = ++dfs_cnt; int i; for(i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].v; if(!pre[v]) { Tarjan(v); lowlink[u] = min(lowlink[u],lowlink[v]); } else if(!sccno[v]) { lowlink[u] = min(lowlink[u],pre[v]); } } if(pre[u]==lowlink[u]) { scc_cnt++; int x; do { x = stk.top(); stk.pop(); sccno[x] = scc_cnt; //sccno[x]表示下标为x的节点所在的第几个强连通分量 }while(x!=u); } } void findscc(int n) { memset(pre,0,sizeof(pre)); memset(lowlink,0,sizeof(lowlink)); memset(sccno,0,sizeof(sccno)); dfs_cnt = scc_cnt = 0; while(!stk.empty()) //初始化 以防万一 { stk.pop(); } int i; for(i=1;i<=n;i++) if(!pre[i]) Tarjan(i); } void getNewMap() //重构缩点后的图,存入邻接链表G中 { int i,j; for(i=0;i<=scc_cnt;i++) { G[i].clear(); in[i] = 0; } memset(mark,0,sizeof(mark)); for(i=0;i<edge_cnt;i++) { int v = edge[i].v; int u = edge[i].u; if(sccno[u]!=sccno[v]) { if(!mark[u][v]) //重复边标记 { G[sccno[u]].push_back(sccno[v]); in[sccno[v]]++; //入度统计 } mark[u][v] = 1; } } } int cntInid() //计算入度为0的位置,以及是不是一个 { int i,cnt=0,id=0; for(i=1;i<=scc_cnt;i++) { if(!in[i]) { cnt++; id = i; } } if(cnt==1) return id; return 0; } int isOK() //用拓扑排序判断是否可行 { int id = cntInid(); if(!id) return 0; int i; in[id] = -1; for(i=0;i<G[id].size();i++) { in[G[id][i]]--; } if(G[id].size()>0) return isOK(); return 1; } int main() { int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); int i; init(); for(i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); addEdge(a,b); } findscc(n); //求强连通分量 if(scc_cnt==1) //如果只有一个那么肯定可行 { puts("Yes"); continue; } getNewMap(); //用强连通分量缩点,重构图 if(isOK()) puts("Yes"); //拓扑排序判断 else puts("No"); } return 0; }
相关文章推荐
- 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) - from lanshui_Yang
- 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? 单向连通图判定
- 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缩点+判断链
- POJ 2762 Going from u to v or from v to u? (Tarjan) - from lanshui_Yang
- poj2762 Going from u to v or from v to u?
- poj 2762 Going from u to v or from v to u(targan缩点+拓扑排序)
- poj 2762 Going from u to v or from v to u?(SCC缩点+拓扑排序)
- 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? (强连通分量缩点+拓扑排序)
- 【缩点+拓扑判链】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?
- POJ 2762 Going from u to v or from v to u?