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
Source
BestCoder Round #1
拓扑排序加优先队列 , 放在hdu上的测试 丧心病狂的卡了时间 用输入挂解决,再就是题目中要求编号小的尽量放前面,因此是逆序建图,然后优先队列先处理大的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
| #include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
const int maxn=30010;
using namespace std;
vector<int> e[maxn];
int n,m,in[maxn],ans[maxn],cnt;
struct cmp
{
bool operator ()(int &a,int &b){
return a<b;//最大值优先
}
};
void read2(int &x)
{
char c;
bool neg = false;
while(((c=getchar())<'0'||c>'9')&&c!='-');
if(c=='-')
{
neg = true;
while((c=getchar())<'0'||c>'9');
}
x= c-'0';
while(c=getchar(),c>='0'&&c<='9') x= x*10+c-'0';
if(neg) x=-x;
}
void topo()
{
priority_queue<int,vector<int>,cmp> q;
for(int i=1;i<=n;i++)
if(in[i]==0) q.push(i);
int flag=0;
int x,i;
while(!q.empty())
{
x=q.top();
q.pop();
ans[++cnt]=x;
for(i=0;i<e[x].size();i++)
{
in[e[x][i]]--;
if(in[e[x][i]]==0)
q.push(e[x][i]);
}
}
}
int main()
{
int t,a,b,i;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=0;i<=n;i++)
e[i].clear();
memset(in,0,sizeof in);
while(m--)
{
read2(a);read2(b);
e[b].push_back(a);
in[a]++;
}
cnt=0;
topo();
printf("%d",ans[cnt]);
for(i=cnt-1;i>0;i--)
printf(" %d",ans[i]);
puts("");
}
return 0;
}
|