确定比赛名次 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 }