HDU 4857 拓扑排序 优先队列
n个数,已经有大小关系,现给m个约束,规定a在b之前,剩下的数要尽可能往前移。输出序列
大小关系显然使用拓扑结构,关键在于n个数本身就有大小关系,那么考虑反向建图,优先选择值最大的入度为零的点,这样得到的序列就是从大到小的,最后倒序输出就行了。
写这题的时候头好痛阿肚子好痛阿,再也不想熬夜了,一点效率都没有。
/** @Date : 2017-09-29 19:29:12 * @FileName: HDU 4857 拓扑排序 + 优先队列.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair<int ,int> #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; int deg[30010]; vector<int>edg[30010]; int ans[30010]; int top(int n) { priority_queue<int, vector<int>, less<int> >q; for(int i = 1; i <= n; i++) if(deg[i] == 0/* && edg[i].size() > 0*/) q.push(i); int cnt = 0; while(!q.empty()) { int nw = q.top(); q.pop(); for(auto i: edg[nw]) { deg[i]--; if(deg[i] == 0) q.push(i); } ans[cnt++] = nw; } /*for(int i = 1; i <= n; i++) if(deg[i] == 0) ans[cnt++] = i;*/ return cnt; } int main() { int T; cin >> T; while(T--) { int n, m; scanf("%d%d", &n, &m); for(int i = 0; i <= n; i++) edg[i].clear(); MMF(deg); for(int i = 0; i < m; i++) { int x, y; scanf("%d%d", &x, &y); int size = edg[y].size(); edg[y].emplace_back(x); if(size != edg[y].size()) deg[x]++; } int cnt = top(n); for(int i = cnt - 1; i >= 0; i--) printf("%d%s", ans[i], i==0?"\n":" "); } return 0; }