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\n", ans[n]); } return 0; }
NOTE : 一开始每次将入度为0的点添加到ans末尾WA了一发;每次将出度为0的点添加到ans开头和每次将入度为0的点添加到ans末尾还是不一样的。