####题目描述
假设给我们一个任意的图,它可能是也可能不是DAG(有向无圈图),推广拓扑排序算法,以使得给定有向图G的输入,它的输出是以下两者之一:
(a) 一个拓扑排序,于是确定了G为DAG;
或者
(b) G中的一个圈,于是确定了G不是DAG.
注意到输出的解可能不是唯一的,输出任意一个答案即可。
输入
第一行两个数n,m,代表节点数和边数
m行,每行两个数代表一条有向边
测试数据范围:(1<=n<=50,0<=m<2500)
输出
YES
一个拓扑序,数字之间用逗号分隔。
或者
NO
一个圈,数字之间用逗号分隔。
思路
由顶点的入度判断是否有环,若无环,则存在拓扑排序,利用队列,不断加入入度为0的顶点,并调整邻接于该点的顶点的入度,输出拓扑排序;若有环,用深度优先搜索找环,创建数组fath存储父节点,若遇到已标记过的点,则找到了环,利用fath数组输出环。代码中有数组越界的问题,但是我还没有找出来(委屈.jpg)……
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include<iostream> #include<queue> using namespace std; bool* label; int * fath; bool flag = true; void dfs(int**a, int n,int s) { label[s] = true; for (int i = 1; i <= n; i++) { if (a[s][i]) { if (!label[i]) { fath[i] = s; dfs(a, n, i); } else if(flag) { queue<int> q; int tmp = s; while (tmp != i) { q.push(tmp); tmp = fath[tmp]; } q.push(tmp); tmp = q.front(); while (!q.empty()) { cout<<q.front() << ","; q.pop(); } cout << tmp << endl; flag = false; return; } } }
} void isDAG(int**a,int n,int m) { int* indg = new int[n + 1]; label = new bool[n + 1]; queue<int> q; for (int i = 1; i <= n; i++) indg[i] = 0; for (int i = 1; i <= n; i++) { label[i] = false; for (int j = 1; j <= n; j++) indg[j] += a[i][j]; if (a[i][i]) { cout << "NO" << endl; cout << i << "," << i << endl; return; } } while (q.size()<n) { int min = n; int index; for (int i = 1; i <= n; i++) if (indg[i] < min && !label[i]) { min = indg[i]; index = i; label[i] = true; } if (min > 0) { cout << "NO" << endl; break; } else { q.push(index); for (int i = 1; i <= n; i++) indg[i] -= a[index][i]; } } if (q.size() == n) { cout << "YES" << endl; while (q.size() > 1) { cout << q.front() << ","; q.pop(); } cout << q.front() << endl; q.pop(); } else { fath = new int[n + 1]; for (int i = 1; i <= n; i++) { label[i] = false; fath[i] = 0; } for (int i = 1; i <= n&&flag; i++) { if (!label[i]) dfs(a, n,i); } } } int main() { int n, m; cin >> n >> m; int**a = new int*[n + 1]; for (int i = 1; i < n + 1; i++) { a[i] = new int[n + 1]; for (int j = 1; j <= n; j++) a[i][j] = 0; } int x, y; for (int i = 0; i < m; i++) { cin >> x >> y; a[x][y] = 1; } isDAG(a,n,m); system("pause"); return 0; }
|