Problem Description
有N个比赛队(1<=N<=500),编号依次为1,2,3,。。。。,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比赛的结果,即P1赢P2,用P1,P2表示,排名时P1在P2之前。现在请你编程序确定排名。
Input
输入有若干组,每组中的第一行为二个数N(1<=N<=500),M;其中N表示队伍的个数,M表示接着有M行的输入数据。接下来的M行数据中,每行也有两个整数P1,P2表示即P1队赢了P2队。
Output
给出一个符合要求的排名。输出时队伍号之间有空格,最后一名后面没有空格。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
其他说明:符合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;输入数据保证是正确的,即输入数据确保一定能有一个符合要求的排名。
Sample Input
4 3
1 2
2 3
4 3
Sample Output
1 2 4 3
我的拓扑排序是用队列写的,由于这里要求多种可能的时候,按照小到大的编号输出,
所以改为优先队列priority_queue。
优先队列默认大到小输出,所以要重载运算符<,使得从小到大
优先队列取出元素不是 .front() , 而是 .top() .
拓扑排序的思路:
1.用一个inde数组存储每个点的入度,邻接表保存边
2.扫一遍,把入度为0的点加入queue
3.每次从queue里面拿出一个元素,并删除这个元素,然后把这个元素通向的边v的入度-1、
如果v的入度变为0,就把v也加入到queue里面。
给点重新编号可以在点入队的时候,也可以在点出队的时候。
因为每一个点都要编号,所以每个点都要进队一次
设置一个计数器,每次出队时记录,若最后计数器>节点数,说明不是拓扑序。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<queue> 5 #include<vector> 6 7 using namespace std; 8 9 const int maxn=505; 10 11 struct Node 12 { 13 int v; 14 bool operator < (const Node &a) const 15 { 16 return a.v<v; 17 } 18 }; 19 20 vector<int>node[maxn]; 21 int f[maxn]; 22 int inde[maxn]; 23 24 int tot; 25 26 void topo(int n) 27 { 28 tot=1; 29 30 priority_queue<Node>que; 31 while(!que.empty()) 32 que.pop(); 33 34 for(int i=1;i<=n;i++) 35 { 36 if(inde[i]==0) 37 { 38 Node temp; 39 temp.v=i; 40 que.push(temp); 41 } 42 } 43 44 while(!que.empty()) 45 { 46 Node u=que.top(); 47 que.pop(); 48 f[tot++]=u.v; 49 50 for(int i=0;i!=node[u.v].size();i++) 51 { 52 int w=node[u.v][i]; 53 inde[w]--; 54 if(inde[w]==0) 55 { 56 Node temp; 57 temp.v=w; 58 que.push(temp); 59 } 60 } 61 } 62 } 63 64 int main() 65 { 66 int n; 67 68 while(scanf("%d",&n)!=EOF) 69 { 70 int m; 71 scanf("%d",&m); 72 73 memset(inde,0,sizeof(inde)); 74 for(int i=1;i<=n;i++) 75 node[i].clear(); 76 77 int u,v; 78 79 for(int i=1;i<=m;i++) 80 { 81 scanf("%d%d",&u,&v); 82 node[u].push_back(v); 83 inde[v]++; 84 } 85 86 topo(n); 87 88 for(int i=1;i<tot-1;i++) 89 printf("%d ",f[i]); 90 printf("%d ",f[tot-1]); 91 } 92 93 return 0; 94 }