拓扑排序算法

70 阅读1分钟
#include <cstdio>
#include <iostream>
#include <cstring>
#define MAXN 100
#define MAXE 500
using namespace std;

int count = 0;
int vis[MAXN];  //是否访问
int ans[MAXE];  //答案数组
int cnt;        //当前dfs计数
int mark[MAXN]; //标记当前字母出现在变量中

typedef struct
{
    int n, e;
    int arc[100][100];
} Graph;

void CreatGraph(Graph &G)
{
    cin >> G.n;
    cin >> G.e;
    for (int i = 0; i < G.n; i++)
    {
        for (int j = 0; j < G.n; j++)
        {
            G.arc[i][j] = 0;
        }
    }
    for (int i = 0; i < G.e; i++)
    {
        int p, q;
        cin >> p >> q;
        G.arc[p - 1][q - 1] = 1; // p指向q
    }
    for (int i = 0; i < G.n; i++)
        mark[i] = 1;
}
void ShowGraph(Graph &G)
{
    for (int i = 0; i < G.n; i++)
    {
        for (int j = 0; j < G.n; j++)
        {
            cout << G.arc[i][j] << "  ";
        }
        cout << endl;
    }
}
bool ok(Graph &G, int i, int cnt) //如果在ans[0,cnt-1]出现了一个本应在i后面才出现的字母,那么返回false
{
    for (int j = 0; j < cnt; j++)
        if (G.arc[i][ans[j]])
            return false;
    return true;
}
void dfs(Graph &G, int cnt)
{
    if (cnt == G.n)
    {
        count++;
        for (int i = 0; i < G.n; i++)
            printf("%d ", ans[i] + 1);
        printf("\n");
        return;
    }
    for (int i = 0; i < G.n; i++)
    {
        if (mark[i] && !vis[i] && ok(G, i, cnt))
        {
            vis[i] = 1;
            ans[cnt] = i;
            dfs(G, cnt + 1);
            vis[i] = 0;
        }
    }
}
int main()
{
    freopen("input.txt", "r", stdin);

    Graph G;

    CreatGraph(G);
    ShowGraph(G);

    dfs(G, 0); //表示当前正在构造第0个位置
    cout << endl << "共有" << count << "种拓扑排序方法";
    return 0;
}



input.txt

12 16
1 2
1 3
1 4
1 12
2 3
3 5
3 7
3 8
4 5
5 7
6 8
9 10
9 11
9 12
10 12
11 6
8 10
1 2
1 3
1 4
1 12
2 3
3 5
3 7
3 8
4 5
5 7
8 10
1 2
1 3
1 4
2 3
3 5
3 7
3 8
4 5
5 7
6 8
11 14
1 2
1 3
1 4
2 3
3 5
3 7
3 8
4 5
5 7
6 8
9 10
9 11
11 6
6 8