Description:
给出一些关系,形如
<i,j>
<
i
,
j
>
<script type="math/tex" id="MathJax-Element-112">
</script>表示i需要在j前面,求出满足小的元素尽量在前面的序列。
Solution:
倒着拓扑排序。考虑正确性,当前有
i,j
i
,
j
两个元素,且
i>j
i
>
j
,把j放在
i
i
后面肯定更劣,所以先放是正确的。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
int n, m;
int ans[maxn], in[maxn];
vector<int> G[maxn];
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++i) {
G[i].clear();
}
memset(in, 0, sizeof(in));
while(m--) {
int u, v;
scanf("%d%d", &u, &v);
G[v].push_back(u);
++in[u];
}
priority_queue<int> q;
for(int i = 1; i <= n; ++i) {
if(!in[i]) {
q.push(i);
}
}
ans[0] = 0;
while(!q.empty()) {
int u = q.top();
q.pop();
ans[++ans[0]] = u;
for(int i = 0; i < G[u].size(); ++i) {
int v = G[u][i];
if(!--in[v]) {
q.push(v);
}
}
}
if(ans[0] != n) {
puts("Impossible!");
} else {
for(int i = n; i; --i) {
printf("%d ", ans[i]);
}
puts("");
}
}
return 0;
}