输出拓扑排序的所有可能结果(题目来源:算法分析与设计及其案例教程第五章课后习题第五题)

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

感谢您的查看。
再一次感谢尊贵的csdn博主focus_best,再一次贴出博主的文章地址
https://blog.csdn.net/u013480600/article/details/30315289/

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/dajin5776/article/details/83186385
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞