BZOJ4010 HNOI2015 菜肴制作 拓扑排序+贪心

题意:给定限制条件(a,b)表示a必须在b之前,求所有合法序列中,小的数尽量在前面的方案

题解:首先我们根据限制条件建反向图,然后在反向图上求字典序最小的拓扑序(队列改为堆),逆序输出即可。

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

const int MAXN=100000+2;
struct HASH{
    int u;
    HASH *next;
    HASH(){}
    HASH(int _u,HASH *_next):u(_u),next(_next){}
}*table[MAXN],mem[MAXN*2];
int N,M,Q,cnt,ans[MAXN],degree[MAXN];
priority_queue<int> q;

void Insert(int u,int v){ table[u]=&(mem[cnt++]=HASH(v,table[u]));}

void Topology_Sort(){
    while(!q.empty()) q.pop();

    for(int i=1;i<=N;i++)
        if(!degree[i]) q.push(i);

    while(!q.empty()){
        ans[++cnt]=q.top(),q.pop();
        for(HASH *p=table[ans[cnt]];p;p=p->next){
            degree[p->u]--;
            if(!degree[p->u]) q.push(p->u);
        }
    }
}

int main(){
    scanf("%d",&Q);
    while(Q--){
        memset(table,0,sizeof(table));
        memset(degree,0,sizeof(degree));
        cnt=0;

        scanf("%d %d",&N,&M);
        for(int i=1,u,v;i<=M;i++){
            scanf("%d %d",&u,&v);
            Insert(v,u),degree[u]++;
        }

        cnt=0,Topology_Sort();
        if(cnt!=N) printf("Impossible!\n");
        else{
            for(int i=N;i;i--) printf("%d ",ans[i]);
            printf("\n");
        }
    }

    return 0;
}

时间: 2024-10-05 23:47:47

BZOJ4010 HNOI2015 菜肴制作 拓扑排序+贪心的相关文章

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

[BZOJ4010][HNOI2015]菜肴制作 Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴之间口味搭配的问题,某些菜肴必须在另一些菜肴之前制作,具体的,一共有 M 条形如“i 号菜肴‘必须’先于 j 号菜肴制作”的限制,我们将这样的限制简写为<i,j>.现在,酒店希望能求出一个最优的菜肴的制作顺序,使得小 A能尽量先吃到质量

bzoj 4010: [HNOI2015]菜肴制作 拓扑排序

4010: [HNOI2015]菜肴制作 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://uoj.ac/problem/67 Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴之间口味搭配的问题, 某些菜肴必须在另一些菜肴之前制作,具体的,一共有 M 条形如“i 号菜肴‘必须’

BZOJ 4010 HNOI2015 菜肴制作 拓扑排序+堆

题目大意:给定一张无向图,求一个拓扑序,使: 1的位置最靠前 在保证上面的条件下使2的位置最靠前 在保证上面的条件下使3的位置最靠前 -- 注意不是字典序最小!例如样例3 建立反图,对反图求字典序最大的拓扑序,然后反向输出即可. 我不知道为什么.真的不知道. 求个解答在线等. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001

bzoj4010: [HNOI2015]菜肴制作【拓扑排序】

想到了一个分治方法,每一次尽量放小的那个,把它依赖的放在左边,不依赖的放在右边. TLE 80: 1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a, b) for (int i = a; i < b; i++) 5 #defin

cogs1958 菜肴制作 拓扑排序

链接:http://cogs.pro/cogs/problem/problem.php?pid=1958 题意:给出一些约束条件,要求得出字典序最小的符合所有条件的方案. 这道题很显然是一个在$AOE$上的程序流程问题,显然是一个拓扑排序.但是这个拓扑排序有点意思,因为它要求字典序最小. 那么我们就要找出一种方法,使得最小的出现在最前面,那么我们就考虑用堆维护,倒序建边. 如果我们正序建边,很有可能我们选取了一个点之后再向下走发现了一个更小的点,而且这个更小的点还是可以放在前面的.而如果倒序建边

B4010 菜肴制作 拓扑排序(附随机跳题代码)

今天写了一个自己的随机跳题小程序,第一次试发现跳的全是不可做题,但是在周围我一眼看见了这个题,不能说一眼看出来,但是也是比较有思路,所以就做他了! 做得比较顺利,做完之后美滋滋,突然发现样例第三组过不了...然后发现自己算法有问题...GG,又想了一个超复杂的算法,刚开始写就放弃了,根本没法写. 于是看题解(本来以为自己能A),就看了一行就明白了,只要倒着存边再倒着输出就行了!!!QAQ!! 跳题代码: #include<iostream> #include<cstdio> #in

bzoj4010: [HNOI2015]菜肴制作

做法是求逆拓扑序中字典序最大的将其反转则得到答案,粗略理解为对于每个数,把能把比大的能够放在他右边的都放在了右边,所以答案最优. 留坑在此 数据太水第一次du没清零都过了? 1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<algorithm> 6 #include<vector> 7 8 using n

bzoj 4010: [HNOI2015]菜肴制作(优先队列+拓扑排序)

4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec  Memory Limit: 512 MB Submit: 1199  Solved: 583 [Submit][Status][Discuss] Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴之间口味搭配的问题, 某些菜肴必须在另一些菜肴之前制作,具体

【BZOJ 4010】 [HNOI2015]菜肴制作

4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory Limit: 512 MB Submit: 426 Solved: 242 [Submit][Status][Discuss] Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号为1.由于菜肴之间口味搭配的问题, 某些菜肴必须在另一些菜肴之前制作,具体的,一