版权声明:转载请标明出处 https://blog.csdn.net/weixin_41190227/article/details/89501630
糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。
现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。
同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。
负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。
那么你就要安排大家的顺序。我们保证一定有解。Input
第一行一个整数T(1 <= T <= 5),表示测试数据的个数。
然后对于每个测试数据,第一行有两个整数n(1 <= n <= 30000)和m(1 <= m <= 100000),分别表示人数和约束的个数。
然后m行,每行两个整数a和b,表示有一个约束a号必须在b号之前。a和b必然不同。Output
对每个测试数据,输出一行排队的顺序,用空格隔开。
Sample Input
1 5 10 3 5 1 4 2 5 1 2 3 4 1 4 2 3 1 5 3 5 1 2Sample Output
1 2 3 4 5
题目大意:中文题。。。
解题思路: 对其进行拓扑排序,要求编号小的尽量排在前面,用优先队列维护。最后倒着输出即可。
/* @Author: Top_Spirit @Language: C++ */ #include <bits/stdc++.h> using namespace std ; typedef long long ll ; typedef pair < ll, ll > P ; const int Maxn = 3e4 + 10 ; const int INF = 1e18 ; int n, m ; vector < int > ve[Maxn] ; int cnt[Maxn] ; priority_queue < int > que ; vector < int > ans ; void init(){ for (int i = 1; i <= n; i++){ ve[i].clear() ; cnt[i] = 0 ; } while (!que.empty()) que.pop() ; ans.clear() ; } void solve (){ for (int i = 1; i <= n; i++) { if (cnt[i] == 0) que.push(i) ; } while (!que.empty()){ int tmp = que.top() ; que.pop() ; ans.push_back(tmp) ; for (int i = 0; i < ve[tmp].size(); i++){ int v = ve[tmp][i] ; cnt[v]-- ; if (cnt[v] == 0) que.push(v) ; } } for (auto i = ans.rbegin(); i != ans.rend(); i++){ if (i == ans.rbegin()) cout << *i ; else cout << " " << *i ; } cout << endl ; } int main (){ ios_base::sync_with_stdio(false) ; cin.tie(0) ; cout.tie(0) ; int T ; cin >> T ; while (T--){ cin >> n >> m ; init() ; for (int i = 0; i < m; i++){ int u, v ; cin >> u >> v ; ve[v].push_back(u) ; cnt[u]++ ; } solve () ; } return 0 ; }