POJ 1094 Sorting It All Out (拓扑排序,有向图判环)
来源:互联网 发布:蒙特卡洛模拟算法 编辑:程序博客网 时间:2024/05/29 00:34
题目链接:http://poj.org/problem?id=1094
思路:因为要找第一个满足拓扑排序的或是有环的,所以要从第一个输入就开始判断。这里要注意一点,如果判断时发现有环了,那么后面都不用管了,答案就是有环;如果判断时发现满足拓扑排序了,那么后面也不用管了(不管后面有没有和前面形成环),答案就是满足拓扑。
先判断环,再判断拓扑排序比较方便。判环时,可以用DFS,方法如下,令vis[i] == 0表示结点i还没被访问、vis[i] == -1表示结点正在访问、vis[i] == 1表示节点已访问完成,如果在访问的过程中发现某个子结点的vis为-1,则存在环。若结点i访问完成并且没有环,则令vis[i] == 1,后面再扫到v时直接跳过即可(因为i点不在环中)。
判断完环后,再判断拓扑排序就简单了(这里的拓扑排序是必须满足任意两点都可比较)。从图中找入度为0的结点,若个数大于1,则不满足,否则删除该点即该点所连的边,继续重复前面的过程,直到所有点被删光为止。
#include<cstdio>#include<cstring>#include<string>#include<cctype>#include<iostream>#include<set>#include<map>#include<cmath>#include<sstream>#include<vector>#include<stack>#include<queue>#include<bitset>#include<algorithm>#define fin() freopen("A.txt","r",stdin)#define fout() freopen("B.txt","w",stdout)typedef long long ll;using namespace std;const int maxn = 30;string ans;vector<int> G[maxn];int vis[maxn];int degree[maxn];int n, m;bool dfs(int u) { if(vis[u] == -1) return false; vis[u] = -1; for(int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if(vis[v] == 1) continue; if(!dfs(v)) return false; } vis[u] = 1; return true;}bool is_circle() { memset(vis, 0, sizeof vis); for(int i = 0; i < n; i++) if(!vis[i]){ if(!dfs(i)) return true; } return false;}bool is_topo() { string s; int ru[maxn]; memset(vis, 0, sizeof vis); for(int i = 0; i < n; i++) ru[i] = degree[i]; bool ok = true; for(;;) { int cnt = 0, temp = 0; for(int i = 0; i < n; i++) { if(!ru[i] && !vis[i]) { cnt++; vis[i] = 1; temp = i; } } if(cnt != 1) { if(cnt > 1) ok = false; break; } s += (char)(temp+'A'); for(int i = 0; i < G[temp].size(); i++) { int v = G[temp][i]; ru[v]--; } } if(ok) ans = s; return ok;}int main() { while(scanf("%d%d", &n, &m) && n) { memset(degree, 0, sizeof degree); for(int i = 0; i < n; i++) G[i].clear(); int circle = 0, topo = 0; for(int i = 1; i <= m; i++) { char s[5]; scanf("%s" ,s); if(circle || topo) continue; int u = s[0] - 'A', v = s[2] - 'A'; degree[v]++; G[u].push_back(v); if(is_circle()) circle = i; if(!circle && !topo && is_topo()) topo = i; } if(circle) printf("Inconsistency found after %d relations.\n", circle); else if(topo) printf("Sorted sequence determined after %d relations: %s.\n", topo, ans.c_str()); else printf("Sorted sequence cannot be determined.\n"); } return 0;}
0 0
- POJ 1094 Sorting It All Out (拓扑排序,有向图判环)
- POJ 1094Sorting It All Out(拓扑排序)
- [ACM] POJ 1094 Sorting It All Out (拓扑排序)
- poj 1094 Sorting It All Out (拓扑排序)
- POJ 1094-Sorting It All Out(拓扑排序)
- POJ 题目1094Sorting It All Out(拓扑排序)
- poj 1094 Sorting It All Out(拓扑排序)
- POJ 1094 Sorting It All Out(拓扑排序)
- POJ-1094---Sorting It All Out(拓扑排序)
- POJ 1094 Sorting It All Out (拓扑排序)
- POJ 1094 -- Sorting It All Out (拓扑排序)
- POJ-1094-Sorting It All Out(拓扑排序)
- POJ 1094 Sorting It All Out(拓扑排序)
- POJ 1094 Sorting It All Out(拓扑排序)
- POJ-1094 Sorting It All Out (拓扑排序)
- POJ 1094 Sorting It All Out (拓扑排序)
- poj 1094 Sorting It All Out (拓扑排序)@
- poj 1094 Sorting It All Out(拓扑排序)
- CiteSpace学习笔记
- 车载导航不支持播放全部的mp3音乐的解决办法--------fwqlzz love is for ever
- 头文件,支持文件和主文件三者之间的关系
- Android开发常犯错误
- uva10720
- POJ 1094 Sorting It All Out (拓扑排序,有向图判环)
- 数据的酷炫可视化
- 【Unity优化】构建一个拒绝GC的Lis
- Mac SecureCRT 8.0.2破解
- 细谈select函数(C语言)
- 回调函数
- UVa10491(紫书326)奶牛与轿车
- sql语句中取整数和小数部分
- 自动化部署脚本详解