hdu 4857 逃生(拓扑排序)

题目链接

题目大意就是:给你一些先后关系,然后输出它们的拓扑序,但是和普通的不一样的地方,输出使编号小的数字尽量靠前的拓扑序,而不一定是字典序。
例如:

4—>2
5—>1—>3

正常情况下字典序最小的拓扑序应该是:4 2 5 1 3
这种规则下,则应该是: 5 1 4 2 3

解法:自己其实是没有想到看题解的QAQ

在当前入度为0的点中,我们先输出哪个并不能完全取决于这个点的大小,而是跟它之后的点尾部有关系。编号小的尽量靠前,其实也是编号大的尽量靠后,我们可以得出结论:大的尾部一定是排在最后的。所以我们可以反向建图,进行拓扑排序,并在优先队列中从大到小排列,每次取编号最大的那个。

#include <bits/stdc++.h>

using namespace std;
const int maxm= 1e5+10;
const int maxn=3e4+10;
int n,m;
int in[maxn];
struct Node{
    int to,next;
}node[maxm];
int head[maxn],cnt;
void init()
{
    memset(head,-1,sizeof(head));
    cnt=0;
    memset(in,0,sizeof(in));
}
void add(int u,int v)
{
    node[cnt].to=v;
    node[cnt].next=head[u];
    head[u]=cnt++;
}

int ans[maxn];
void toposort()
{
    priority_queue<int > que;
    for(int i=1;i<=n;i++)
        if(in[i]==0) que.push(i);
    int cnt=0;
    while(!que.empty())
    {
        int u=que.top();
        que.pop();
        ans[cnt++]=u;
     //   printf("%d%c",u,cnt==n?'\n':' ');
        for(int i=head[u];~i;i=node[i].next)
        {
            int v=node[i].to;
            in[v]--;
            if(in[v]==0) que.push(v);
        }
    }

}

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        init();
        for(int i=0;i<m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            add(v,u);
            in[u]++;
        }
        toposort();
        for(int i=n-1;i>=0;i--)
            printf("%d%c",ans[i],i==0?'\n':' ');
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值