拓扑排序

看了参加ACM的人写的程序,只能说他们成魔了啊....空间太节省了....

 

  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 #include <queue>
  5 #include <set>
  6 #include <algorithm>
  7 #include <map>
  8 #include <stack>
  9 using namespace std;
 10 
 11 void findOrder(int cnt, map<int, int> depNum, map<int, map<int, bool> > dep) {
 12 //拓扑排序
 13     for (int i = 0; i < cnt; ++i) {
 14         int choice = 2550;
 15         for (int j = 0; j < cnt; ++j) {
 16             if (depNum[j] == 0) {
 17                 choice = min(choice, j);
 18                 break;
 19             }
 20         }
 21 
 22         if (choice == 2550) {
 23             cout << "circle!";
 24         }
 25         depNum[choice] = -1;
 26         for (int j = 0; j < cnt; ++j) {
 27             if (dep[choice][j]) {
 28                 depNum[j]--;
 29             }
 30         }
 31         cout << choice << " ";
 32     }
 33 }
 34 
 35 
 36 /*==================================================*\
 37  |  拓扑排序
 38  | INIT:edge[][] 置为图的邻接矩阵;count[0…i…n-1]: 顶点i 的入度.
 39  | 和TopoOrder实现的原理是一样的,只是没有用count。
 40  \*==================================================*/
 41 void TopoOrder_easy(int n, map<int, int> count, map<int, map<int, bool> > edge) {
 42     int i, top = -1;
 43     stack<int> sh;
 44     for (i = 0; i < n; ++i)
 45         if (count[i] == 0) { //  下标模拟堆栈
 46             sh.push(i);
 47             top = i;
 48         }
 49 
 50     for (i = 0; i < n; ++i)
 51         if (sh.empty()) {
 52             cout << " circle\n";
 53             return;
 54         } else {
 55 
 56             int j = sh.top();
 57             sh.pop();
 58             cout << j << " ";
 59             for (int k = 0; k < n; ++k)
 60                 if (edge[j][k] && (--count[k]) == 0) {
 61                     sh.push(k);
 62                 }
 63 
 64         }
 65 }
 66 
 67 
 68 
 69 /*==================================================*\
 70  |  拓扑排序
 71  | INIT:edge[][] 置为图的邻接矩阵;count[0…i…n-1]: 顶点i 的入度.
 72  \*==================================================*/
 73 void TopoOrder(int n, map<int, int> count, map<int, map<int, bool> > edge) {
 74     int i, top = -1;
 75     for (i = 0; i < n; ++i)
 76         if (count[i] == 0) { //  下标模拟堆栈
 77             count[i] = top;
 78             top = i;
 79         }
 80 
 81     for (i = 0; i < n; ++i)
 82         if (top == -1) {
 83             cout << " circle\n";
 84             return;
 85         } else {
 86             int j = top;
 87             top = count[top];
 88             cout << j << " ";
 89             for (int k = 0; k < n; ++k)
 90                 if (edge[j][k] && (--count[k]) == 0) {
 91                     count[k] = top;
 92                     top = k;
 93                 }
 94         }
 95 }
 96 
 97 int main() {
 98     map<int, int> count;
 99     map<int, map<int, bool> > edge;
100 
101     for (int i = 0; i < 4; i++)
102         for (int j = 0; j < 4; j++)
103             edge[i][j] = 0;
104     edge[3][1] = edge[3][0] = 1;
105 
106     for (int i = 0; i < 4; i++)
107         for (int j = 0; j < 4; j++) {
108             if (edge[i][j]) {
109                 count[j]++;
110             }
111         }
112     TopoOrder_easy(4, count, edge);
113     cout<<endl;
114     TopoOrder(4, count, edge);
115     cout << endl;
116     findOrder(4, count, edge);
117     return 0;
118 }

 

 

posted on 2012-07-23 21:58  kakamilan  阅读(122)  评论(0编辑  收藏  举报

导航