Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4265 Accepted Submission(s): 1185
Problem Description
糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。 现在有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 2
Sample Output
1 2 3 4 5
Author
CLJ
priority_queue有三个参数,如果最后两个缺省,默认按照大顶堆的方式平排,将最大的元素拿到对头。每次从最大元素开始取。如果有特殊安排,只有当小的元素被取出后大元素的度数变为零才可以进队列后排在对头出队列。
#include#include #include #define MAXN 100002using namespace std;int head[MAXN], indegree[MAXN], ans[MAXN];struct node{ int to, next;}edge[MAXN];int t, n, m, a, b;void solved() { //大顶堆排序 priority_queue que; int u, id = 1; for(int i = 1; i <= n; i++) if(!indegree[i]) que.push(i); while(!que.empty()){ ans[id++] = u = que.top(); que.pop(); for(int i = head[u]; i != -1; i = edge[i].next) { if(!--indegree[edge[i].to]) que.push(edge[i].to); } } for(int i = n; i >= 1; i--) { if(i != 1) printf("%d ", ans[i]); else printf("%d\n", ans[i]); }}int main() { scanf("%d", &t); while (t--) { memset(indegree, 0, sizeof(indegree)); memset(head, -1, sizeof(head)); scanf("%d%d", &n, &m); for(int i = 0; i < m; i++){ scanf("%d%d", &a, &b); edge[i].to = a; edge[i].next = head[b]; head[b] = i; indegree[a]++; } solved(); } return 0;}