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

【题目大意】

是要求N个点的一个拓扑序,且满足以下条件:编号1的位置尽可能靠前,在满足所有限制,编号2的位置尽可能靠前,以此类推。

【思路】

一开始觉得优先队列维护一下拓扑就好了。然而样例告诉我们是不可以的。如果限制条件是:

5 2

4 3

最后出来的会是1-4-3-5-2,而答案应该是1-5-2-4-3。

由此可以发现,如果正向拓扑出来的是“字典序最小”,而不是“编号小的尽可能靠前”。

所以逆向拓扑。

证明……算了困了,改天再纠结吧。丢个链接存个档。?

不妨认为我们这样得到的不是最优解,那么令这样得到的序列为a,然后最优解是b。
我们从后往前开始找到第一位两个序列不同的一位设为k,那么a[k]!=b[k],且a[k]>b[k]。(由a的构造方式可知)(先假设这个k存在,再证出矛盾)
再设a[k]出现的b的p位置,即b[p]=a[k]。再设b[p] b[p+1]……b[k]这个子序列为C。
那么b[p]一定不是C中的最小元素,因为有b[k]<b[p]=a[k]。
然后不妨设b[q]为C的最小元素。然后我们把b[p]移到b[k]的位置,得到序列bb。
如果bb合法的话,那么我们就得到了一个比b优的解,这与b是最优解矛盾。
(因为b[q]的位置前移了一位,我们要求编号小的尽可能靠前)
但bb显然是合法的。因为在a序列中k以及后面的是合法的,那么b后面也这么做一定也是合法的。
所以一定不存在某个k,使得a[k]!=b[k]。也就是说a=b。
所以算法正确性得证。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=100000+50;
 4 int n,m,in;
 5 vector<int> E[MAXN];
 6 priority_queue<int> que;
 7 int ans[MAXN],inn[MAXN];
 8
 9 void init()
10 {
11     scanf("%d%d",&n,&m);
12     memset(inn,0,sizeof(inn));
13     for (int i=1;i<=n;i++) vector<int>().swap(E[i]);
14     for (int i=0;i<m;i++)
15     {
16         int u,v;
17         scanf("%d%d",&u,&v);
18         inn[u]++;
19         E[v].push_back(u);
20     }
21 }
22
23 void solve()
24 {
25     while (!que.empty()) que.pop();
26     ans[0]=0;
27     for (int i=1;i<=n;i++) if (!inn[i]) que.push(i);
28     while (!que.empty())
29     {
30         int u=que.top();que.pop();
31         ans[++ans[0]]=u;
32         for (int i=0;i<E[u].size();i++)
33         {
34             int v=E[u][i];
35             inn[v]--;
36             if (!inn[v]) que.push(v);
37         }
38     }
39     if (ans[0]<n) puts("Impossible!");
40         else
41         {
42             for (int i=ans[0];i>=1;i--) printf("%d ",ans[i]);
43             printf("\n");
44         }
45 }
46
47 int main()
48 {
49     int T;
50     scanf("%d",&T);
51     while (T--)
52     {
53         init();
54         solve();
55     }
56     return 0;
57 }
时间: 2024-12-14 05:17:07

【拓扑排序】BZOJ4010-[HNOI2015]菜肴制作的相关文章

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

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

题意:给定限制条件(a,b)表示a必须在b之前,求所有合法序列中,小的数尽量在前面的方案 题解:首先我们根据限制条件建反向图,然后在反向图上求字典序最小的拓扑序(队列改为堆),逆序输出即可. #include <queue> #include <functional> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include

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

【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: 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: 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]菜肴制作

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.由于菜肴之间口味搭配的问题, 某些菜肴必须在另一些菜肴之前制作,具体的,一

4010: [HNOI2015]菜肴制作

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

[HNOI2015]菜肴制作 题解(自带口胡证明)

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