【拓扑】BZOJ4010 [HNOI2015]菜肴制作

博客详细解析了BZOJ4010题目,强调题意并非求最小字典序,而是要求在确保前i个任务完成后,再进行第i+1个任务的条件下,找到反图的最大拓扑字典序解决方案。文章通过实例说明,并提供了示例程序来阐述解题思路。
摘要由CSDN通过智能技术生成

题面在这里

首先要明确,题意不等价于求最小字典序

例如: n=4,31,24

此时应输出 3124

因为题目要求的是在保证 1i 先完成的情况下,再考虑 i+1

所以求反图的最大拓扑字典序即可

示例程序:

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define cl(x,y) memset(x,y,sizeof(x))
using namespace std;

const int maxn=100005;
int tst,n,e,f[maxn],ans[maxn];
int tot,nxt[maxn],son[maxn],lnk[maxn];
priority_queue<int> Q;
inline void add(int x,int y){
    son[++tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;
}
int main(){
    scanf("%d",&tst);
    while (tst--){
        scanf("%d%d",&n,&e);
        while (!Q.empty()) Q.pop();
        cl(lnk,0);tot=0;cl(f,0);
        for (int i=1,x,y;i<=e;i++)
         scanf("%d%d",&x,&y),add(y,x),f[x]++;
        for (int i=1;i<=n;i++)
         if (!f[i]) Q.push(i);
        ans[0]=0;
        while (!Q.empty()){
            int x=Q.top();Q.pop();ans[++ans[0]]=x;
            for (int j=lnk[x];j;j=nxt[j]){
                f[son[j]]--;
                if (!f[son[j]]) Q.push(son[j]);
            }
        }
        if (ans[0]<n) printf("Impossible!");else
         for (int i=ans[0];i;i--) printf("%d ",ans[i]);
        putchar('\n');
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值