HDU 1285 确定比赛名次 拓扑排序水题

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 }
View Code
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/-maybe/p/4491896.html