HDU 4857 逃生(拓扑排序最小字典序)

题意:中文题

思路:我一直以为自己过掉了这个题,直到有天upc 训练时发现没过,现在打卡

这个题其实就是拓扑排序加上优先队列,因为我们对于没有入度的点呢,可以丢到优先队列中,这样就会弹出最小字典序(2018第一场多校耻辱下机,被1004卡3小时,思路差不多疯狂T)

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

const int maxn=30005;
int n,m,ans;
bool vis[maxn];
int in[maxn];
vector<int>edge[maxn];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&m);
        memset(in,0,sizeof(in));
        for(int i=1;i<=n;i++)edge[i].clear();
        for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            in[u]++;
            edge[v].push_back(u);
        }
//        printf("test
");
        priority_queue<int> q;
        for(int i=1;i<=n;i++){
            if(in[i]==0)q.push(i);
        }
        memset(vis,0,sizeof(vis));
        vector<int>res;
        ans=0;
//        printf("test
");
        while(!q.empty()){
            ans++;
//            printf("test %d %d
",ans,q.size());
            int now=q.top();
            res.push_back(now);
            q.pop();
            vis[now]=1;
            for(int i=0;i<edge[now].size();i++){
                int v=edge[now][i];
                in[v]--;
                if(in[v]==0)q.push(v);
            }
        }
//        printf("test
");
        for(int i=res.size()-1;i>=0;i--){
            if(i==res.size()-1) printf("%d",res[i]);
            else printf(" %d",res[i]);
        }
        puts("");

    }
    return 0;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9357139.html