POJ1094——拓撲排序和它的唯一性


比較模板的topological-sort題,關鍵在於每個元素都嚴格存在唯一的大小關系,而一般的拓撲排序只給出一個可能解,這就需要每趟排序的過程中監視它是不是總堅持一條唯一的路徑。

算法導論里面的拓撲排序運用的是DFS the DAG,記錄每個頂點的進入時間和離開時間,根據其先后插入單鏈表的做法。而我認為一種方法是更直觀的,就是維護一個入度為0的頂點集合(我用的隊列其實沒差),每次對其中一個加入結果序列——同時刪除它的所有出邊——更新其他點的入度的做法,在我的算法數據結構實現模板里有正確實現https://github.com/jily16/ACMCodes(打廣告

在判斷拓撲排序結果唯一性時這種方法也表現出了一個優勢,每次訪問0入度集合時查看大小,當元素多於1的時候可行的選擇就出現了分歧——即可判定此DAG的拓撲排序不唯一(當然本題的信息在不斷更新,所以不能立刻判死)。

AC代碼:

  1 #include <vector>
  2 #include <iostream>
  3 #include <queue>
  4 using namespace std;
  5 //POJ1094
  6 int const INF = 0x3f3f3f3f;
  7 //返回空數組說明暫時不行
  8 //cyclic說明矛盾
  9 vector<int> ts(vector<vector<int> > const &g, bool &cyclic)
 10 {
 11     int n = g.size();
 12     vector<int> d(n);
 13     for (int i = 0; i < n; ++i)
 14     {
 15         for (int j = 0; j < n; ++j)
 16         {
 17             if (g[i][j] < INF)
 18             {
 19                 ++d[j];
 20             }
 21         }
 22     }
 23     queue<int> q;
 24     for (int i = 0; i < n; ++i) if (d[i] == 0) q.push(i);
 25     int d0;
 26     int tot = 0;
 27     bool not_unique = false;
 28     vector<int> ans;
 29     while (!q.empty())
 30     {
 31         if (q.size() > 1)
 32         {
 33             not_unique = true;    //解不唯一
 34         }
 35         d0 = q.front();
 36         q.pop();
 37         ans.push_back(d0);
 38         ++tot;
 39         for (int i = 0; i < n; ++i)
 40         {
 41             if (d[i] != 0 && g[d0][i] < INF)
 42             {
 43                 --d[i];
 44                 if (d[i] == 0)
 45                 {
 46                     q.push(i);
 47                 }
 48             }
 49         }
 50     }
 51     if (tot != n) cyclic = true;
 52     if (not_unique) return vector<int>();
 53     else return ans;
 54 }
 55 int main()
 56 {
 57     int n, m;
 58     while (cin >> n >> m && n && m)
 59     {
 60         bool done = false;
 61         vector<vector<int> > g;
 62         char alp1, alp2;
 63         char lessthan;
 64         int num1, num2;
 65         for (int i = 0; i < m; ++i)
 66         {
 67             cin >> alp1 >> lessthan >> alp2;
 68             if (done) continue;
 69             num1 = alp1 - 'A';
 70             num2 = alp2 - 'A';
 71             int bignum = max(num1, num2);
 72             //extend the graph
 73             if (g.size() < bignum + 1)
 74             {
 75                 int ori_size = g.size();
 76                 for (int i = 0; i < ori_size; ++i)
 77                 {
 78                     for (int j = 0; j < bignum + 1 - ori_size; ++j)
 79                     {
 80                         g[i].push_back(INF);
 81                     }
 82                 }
 83                 for (int i = 0; i < bignum + 1 - ori_size; ++i)
 84                 {
 85                     g.push_back(vector<int>(bignum + 1, INF));
 86                 }
 87             }
 88             g[num1][num2] = 1;
 89             //judge from here
 90             bool cycle = false;
 91             if (g.size() < n)
 92             {
 93                 ts(g, cycle);
 94                 if (cycle)
 95                 {
 96                     cout << "Inconsistency found after " << i + 1 << " relations.\n";
 97                     done = true;
 98                 }
 99                 else
100                 {
101                     if (i == m - 1)
102                     {
103                         cout << "Sorted sequence cannot be determined.\n";
104                         done = true;
105                     }
106                 }
107             }
108             else
109             {
110                 vector<int> ans = ts(g, cycle);
111                 if (cycle)
112                 {
113                     cout << "Inconsistency found after " << i + 1 << " relations.\n";
114                     done = true;
115                 }
116                 else
117                 {
118                     if (ans.size() != 0)
119                     {
120                             cout << "Sorted sequence determined after " << i + 1 << " relations: ";
121                             for (int i = 0; i < n; ++i) cout << (char)(ans[i] + 'A');
122                             cout << ".\n";
123                             done = true;
124                     }
125                     else
126                     {
127                         if (i < m - 1) continue;
128                         else
129                         {
130                             cout << "Sorted sequence cannot be determined.\n";
131                             done = true;
132                         }
133                     }
134                 }
135             }
136         }
137     }
138     return 0;
139 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM