确定比赛名次 HDU - 1285

原题链接

考察:拓扑排序

思路:

        如果没有按字典序最小的输出就可以直接套模板,但是要求字典序最小.首先想到队列里的元素一定是没有入度的点,当这些点在队列中说明前面已经确定好顺序了.而队列里的点的顺序是不会改变拓扑序列的性质.因此可以用大根堆或者sort排序AC此题

易错:

        数据好像有重边,但拓扑排序的重边好像没什么意义

 1 #include <iostream>
 2 #include <queue>
 3 #include <set>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef pair<int,int> pii;
 7 const int N = 510;
 8 int h[N],d[N],e[N],ne[N],idx,n,m,q[N]; 
 9 void add(int a,int b)
10 {
11     e[idx] = b,ne[idx]=h[a],h[a] = idx++;
12 }
13 void bfs()
14 {
15     int hh=0,tt = -1;
16     for(int i=1;i<=n;i++) if(!d[i]) q[++tt] = i;
17     while(hh<=tt)
18     {
19         int x = q[hh++];
20         for(int i=h[x];i!=-1;i=ne[i])
21         {
22             int j = e[i]; d[j]--;
23             if(!d[j]) q[++tt] = j;
24         }
25         sort(q+hh,q+tt+1);
26     }
27     for(int i=0;i<n;i++) printf("%d%c",q[i],(i==n-1?'\n':' '));
28 }
29 int main()
30 {
31 //    freopen("in.txt","r",stdin);
32     while(scanf("%d%d",&n,&m)!=EOF)
33     {
34         fill(h,h+N,-1); fill(d,d+N,0);idx = 0;
35         //s.clear();
36         for(int i=1;i<=m;i++){
37             pii p; scanf("%d%d",&p.first,&p.second);
38         //    if(s.count(p)) continue;
39             add(p.first,p.second); d[p.second]++; //s.insert(p);
40         }
41         bfs();
42     }
43     return 0;
44 } 

 

posted @ 2021-01-10 23:11  acmloser  阅读(79)  评论(0编辑  收藏  举报