曾经沧海难为水,除却巫山不是云。|

Joey-Wang

园龄:4年3个月粉丝:17关注:0

10.6 拓扑排序

10.6 拓扑排序

http://codeup.hustoj.com/contest.php?cid=100000623

拓扑排序的重要应用——判断一个给定的图是否是 有向无环

A 算法7-12:有向无环图的拓扑排序

image-20200831032509984

题目解析

这道题也没啥好说的,就是注意一点:
⚠️ 用queue结果WA了,样例结果是0 3 1 2,题目中说“请按照题目描述中的算法依次输出图的拓扑有序序列”,题中用的是stack,所以将queue改为stack后AC,样例结果3 0 1 2
这两个答案其实都是正确的拓扑序列,只是因为queue是先进先出,stack是后进先出,所以顺序输出的不一样。而这里要按照题目要求使用stack。
(🙃 所以要看清楚题目的要求)

另,这道题用了 vector<int> ans 存储最后的拓扑系列

代码

#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#define maxV 55
using namespace std;
vector<int> Adj[maxV];
vector<int> ans;
int n, inDegree[maxV] = {0};

bool topologicalSort() {
    stack<int> s;
    int num = 0;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) s.push(i);
    }
    while (!s.empty()) {
        int u = s.top();
        s.pop();
        ans.push_back(u);
        num++; //加入拓扑排序的顶点数+1
        for (int i = 0; i < Adj[u].size(); i++) {
            int v = Adj[u][i];
            inDegree[v]--;
            if (inDegree[v] == 0) s.push(v);
        }
        Adj[u].clear();//清除u的所有出度
    }
    if (num == n) return true;
    else return false;
}

int main() {
    int temp;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &temp);
            if (temp == 1) {
                Adj[i].push_back(j); //出度
                inDegree[j]++; //入度
            }
        }
    }
    if (topologicalSort()) {
        for (int i = 0; i < ans.size(); i++) printf("%d ", ans[i]);
        printf("\n");
    } else printf("ERROR\n");
    return 0;
}

B 确定比赛名次

image-20200831033040148

题目解析

这道题也是常规拓扑排序题目,没啥难的。就是题目要求“符合条件的排名不唯一时,输出编号小的队伍在前”,所以用了priority_queue<int, vector<int>, greater<int>> q;

还有就是,注意题目中编号从1开始

代码

#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>

#define maxV 505
using namespace std;
vector<int> Adj[maxV];
vector<int> ans;
int n, inDegree[maxV] = {0};

bool topologicalSort() {
    int num = 0;
    priority_queue<int, vector<int>, greater<int>> q;
    for (int i = 1; i <= n; i++) { //注意题目中从1开始 !!!
        if (inDegree[i] == 0) q.push(i);
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        ans.push_back(u);
        num++;
        for (int i = 0; i < Adj[u].size(); i++) {
            int v = Adj[u][i];
            inDegree[v]--;
            if (inDegree[v] == 0) q.push(v);
        }
        Adj[u].clear();//因为题目中保证输入的数据一定有符合要求的拓扑排序结果,所以Adj[i]中肯定都能清空,下一组输入用例前就不用循环清空一遍了
    }
    if (n == num) return true;
    else return false;
}

int main() {
    int m, a, b;
    while (scanf("%d%d", &n, &m) && n) {
        ans.clear();
        memset(inDegree, 0, sizeof(inDegree));
        for (int i = 0; i < m; i++) {
            scanf("%d%d", &a, &b);
            Adj[a].push_back(b);
            inDegree[b]++;
        }
        if (topologicalSort()) {
            for (int i = 0; i < ans.size(); i++) {
                printf("%d", ans[i]);
                if (i < ans.size() - 1) printf(" ");
                else printf("\n");
            }
        }
    }
    return 0;
}

本文作者:Joey-Wang

本文链接:https://www.cnblogs.com/joey-wang/p/14541193.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Joey-Wang  阅读(79)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开