輸出拓撲排序的所有可能結果(題目來源:演算法分析與設計及其案例教程第五章課後習題第五題)
阿新 • • 發佈:2018-12-16
這是我在csdn 的第②篇部落格 該篇為C++程式碼 原題問的是實現拓撲排序的方法,但答案給除了所有的拓撲排序的可能。 看到答案這麼寫我就在想如何才能輸出所有拓撲排序的結果?,但我一開始只能寫出輸出一種可能的拓撲排序結果的程式碼,經過一天的查詢資料後在CSDN發現POJ 1270 Following Orders(拓撲排序:輸出所有可能)這篇文章給了我很大幫助,通過改寫(我是菜雞,勉強改改)該博主的ac後的程式碼,可以輸出所有的拓撲排序結果且按字典序排列。在這裡感謝CSDN博主focus_best。 我的題目的圖片:(要求輸出該有向無環圖中的所有的拓撲排序的結果) 改寫後的程式碼(有些細節沒有照顧到,可能會出現一些沒有用到的變數,時間緊迫喲) 編輯器:Code::Blocks 16.01
#include<cstdio> #include<cstring> using namespace std; const int maxn=30; const int maxm=500; int n;//有效字母數 int vis[maxn];//是否訪問 int ans[maxn];//答案陣列 int cnt;//當前dfs計數 bool mark[maxn];//標記當前字母出現在變數中 int gragh[7][7] = { {0,1,1,0,0,0,0},//a {0,0,0,0,1,0,1},//b {0,0,0,0,0,1,0},//c {1,1,1,0,0,1,1},//d {0,0,0,0,0,0,0},//e {0,0,0,0,0,0,0},//f {0,0,0,0,1,1,0}};//g bool ok(int i,int cnt)//如果在ans[0,cnt-1]出現了一個本應在i後面才出現的字母,那麼返回false { for(int j=0;j<cnt;j++) if(gragh[i][ans[j]]) return false; return true; } void dfs(int cnt) { if(cnt==n) { for(int i=0;i<n;i++) printf("%c",ans[i]+'a'); printf("\n"); } else for(int i=0;i<26;i++)if(mark[i]&&!vis[i]&&ok(i,cnt)) { vis[i]=1; ans[cnt]=i; dfs(cnt+1); vis[i]=0; } } int main() { n=7; memset(mark,0,sizeof(mark)); memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) mark[i]=true; dfs(0);//表示當前正在構造第0個位置 return 0; }
最終執行結果: 順便附一下之前只能輸出一種可能的拓撲排序的程式碼 (編輯器:DEVC++) (1) 選擇一個入度為0的頂點並進入佇列; (2) 從隊首出隊,存入陣列,並刪除此頂點的所有出邊(就是將出邊所連線的頂點的入度減1)。 不斷重複這兩個步驟
#include <cstdlib> #include <iostream> #include <queue> #include <stack> #include <memory.h> #include <stdio.h> using namespace std; //結點數為n,用鄰接矩陣gragh[n][n]儲存邊 //用indegree[n] 儲存每個結點的入度 int gragh[7][7] = { {0,1,1,0,0,0,0},//a {0,0,0,0,1,0,1},//b {0,0,0,0,0,1,0},//c {1,1,1,0,0,1,1},//d {0,0,0,0,0,0,0},//e {0,0,0,0,0,0,0},//f {0,0,0,0,1,1,0}};//g int indegree[7] = {1,2,2,0,2,3,2}; int topsort[7]; void topologic(int *toposort,int n){ int cnt = 0; queue<int> q; int i; for(i = 0;i<n;i++){ if(indegree[i]==0) q.push(i); } int cur; while(!q.empty()){ cur = q.front(); q.pop(); topsort[cnt++] = cur; for(i=0;i<n;i++){ if(gragh[cur][i]!=0){ indegree[i]--; if(indegree[i]==0) q.push(i); } } } } int main(int argc, char *argv[]) { int n = 7; memset(topsort,0,sizeof(topsort)); topologic(topsort,n); printf("拓撲排序結果:"); for(int i=0;i<7;i++){ printf("%c ",topsort[i]+'a'); } printf("\n"); system("PAUSE"); return EXIT_SUCCESS; }