hdu4857 拓扑排序

题目大意:

糟糕的事情发生啦,现在大家都忙着逃命。但是逃命的通道很窄,大家只能排成一行。 

现在有n个人,从1标号到n。同时有一些奇怪的约束条件,每个都形如:a必须在b之前。 
同时,社会是不平等的,这些人有的穷有的富。1号最富,2号第二富,以此类推。有钱人就贿赂负责人,所以他们有一些好处。 

负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推。 

那么你就要安排大家的顺序。我们保证一定有解。

基本思路:

就是拓扑排序的基础上加上了限定序号大小,反向存边,优先队列存,反向输出;

这样一开始找找到的就是独立的点或者最后一个点,然后开始进入循环,优先队列默认出最大,那么先出来的就是符合条件的最大的,然后找到和此点有边的点,很显然,每次都是讲满足条件的最大的id存下,最后倒序输出就好了

代码如下:

#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>

using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 50000+10;

int ind[maxn],tp[maxn];
vector<int>gra[maxn];
int main(){
    int cas;
    scanf("%d",&cas);
    while(cas--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            gra[i].clear();
            ind[maxn]=0;
        }
        int u,v;
        while(m--){
            scanf("%d%d",&u,&v);
            ind[u]++;
            gra[v].push_back(u);
        }
        priority_queue<int>pq;
        for(int i=1;i<=n;i++){
            if(!ind[i]){
                pq.push(i);
            }
        }
        int cnt=0;
        while(!pq.empty()){
            int u=pq.top();
            pq.pop();
            tp[cnt++]=u;
            int sz=gra[u].size();
            for(int i=0;i<sz;i++){
                int v=gra[u][i];
                ind[v]--;
                if(!ind[v]){
                    pq.push(v);
                }
            }
        }
        for(int i=cnt-1;i>=0;i--){
            if(i==cnt-1){
                printf("%d",tp[i]);
            }else{
                printf(" %d",tp[i]);
            }
        }
        printf("
");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/imzscilovecode/p/8657098.html