链接:http://codeforces.com/gym/100792/my
题意:给定一个有向无环图,求topo序,要求编号小的尽可能往前放,即在所有可能的topo序中,满足1尽量靠前,然后在这个前提下2尽量靠前,以此类推。
分析:难点在于怎么将编号小的尽量往前放。。可以倒着想,先把出度为0且编号最大的点放在最后面。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 using namespace std;
6 const int maxn=2e5+5;
7 vector<int>G[maxn];
8 struct Edge{
9 int u,v;
10 Edge(int _u,int _v):u(_u),v(_v){}
11 };
12 bool Cmp(Edge a,Edge b){
13 if(a.u==b.u)return a.v<b.v;
14 return a.u<b.u;
15 }
16 bool operator==(Edge a,Edge b){
17 if(a.u==b.u&&a.v==b.v)return true;
18 return false;
19 }
20 struct Node{
21 int order,ind;
22 Node(int r,int in):order(r),ind(in){}
23 };
24 bool operator<(Node a,Node b){
25 if(a.ind==b.ind)return a.order<b.order;
26 return a.ind>b.ind;
27 }
28 int ind[maxn],n,m,topo[maxn];
29 bool Is_delete[2*maxn];
30 priority_queue<Node> Q;
31 void TopoSort(){
32 for(int i=1;i<=n;i++)Q.push(Node(i,ind[i]));
33 int cnt=n-1;
34 while(!Q.empty()){
35 Node node=Q.top();Q.pop();
36 int x=node.order;
37 if(ind[x]!=node.ind)continue;
38 topo[cnt--]=x;
39 for(int i=0;i<G[x].size();i++){
40 ind[G[x][i]]--;
41 Q.push(Node(G[x][i],ind[G[x][i]]));
42 }
43 }
44 }
45 int main(){
46 scanf("%d%d",&n,&m);
47 memset(ind,0,sizeof(ind));
48 memset(Is_delete,0,sizeof(Is_delete));
49 for(int i=0;i<m;i++){
50 int u,v;
51 scanf("%d%d",&v,&u);
52 G[u].push_back(v);
53 ind[v]++;
54 }
55 TopoSort();
56 for(int i=0;i<n;i++){
57 if(i)printf(" ");
58 printf("%d",topo[i]);
59 }
60 printf("\n");
61 return 0;
62 }