HDU-1285-确定比赛名次(拓扑排序)

  • 拓扑排序
    #include "bits/stdc++.h"
    using namespace std;
    // 用来存某个点的入度数量
    int num[505];
    // 用来存某个节点的出度
    set<int> outde[505];
    int ans[505];
    priority_queue<int, vector<int>, greater<int> > qu;
    int main() {
        int n, m, id, victory, defeat;
        while (~scanf("%d%d", &n, &m)) {
            id = 0;
            while (m--) {
                scanf("%d%d", &victory, &defeat);
                // 去重,这题的坑点,输入数据可能会重复defeat被victory多次打败
                if (outde[victory].count(defeat) == 0) {
                    num[defeat]++;
                    outde[victory].insert(defeat);
                }
            }
            // 把入度为0的点加入优先队列
            for (int i = 1; i <= n; i++) {
                if (num[i] == 0) {
                    qu.push(i);
                }
            }
            while (!qu.empty()) {
                // 取出优先队列中编号最小的点并存到ans数组中去;
                int first = qu.top();
                qu.pop();
                ans[++id] = first;
                // 将first的所以出度的入度数量减1;
                for (int i : outde[first]) {
                    num[i]--;
                    // 如果入度变成了0,就加入优先队列
                    if (num[i] == 0) {
                        qu.push(i);
                    }
                }
                outde[first].clear();
            }
            for (int i = 1; i < n; i++) {
                printf("%d ", ans[i]);
            }
            printf("%d
    ", ans[n]);
        }
        return 0;
    }

     NOTE : 一开始每次将入度为0的点添加到ans末尾WA了一发;每次将出度为0的点添加到ans开头和每次将入度为0的点添加到ans末尾还是不一样的。

原文地址:https://www.cnblogs.com/Angel-Demon/p/10260117.html