GYM 100792 K. King's Rout(topo排序+逆向思维)

链接: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("
");
61     return 0;
62 }
原文地址:https://www.cnblogs.com/7391-KID/p/7659149.html