1. 程式人生 > >輸出拓撲排序的所有可能結果(題目來源:演算法分析與設計及其案例教程第五章課後習題第五題)

輸出拓撲排序的所有可能結果(題目來源:演算法分析與設計及其案例教程第五章課後習題第五題)

這是我在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;
}