cogs1958 菜肴制作 拓扑排序

Posted Loser Of Life

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cogs1958 菜肴制作 拓扑排序相关的知识,希望对你有一定的参考价值。

链接:http://cogs.pro/cogs/problem/problem.php?pid=1958

题意:给出一些约束条件,要求得出字典序最小的符合所有条件的方案。

这道题很显然是一个在$AOE$上的程序流程问题,显然是一个拓扑排序。但是这个拓扑排序有点意思,因为它要求字典序最小。

那么我们就要找出一种方法,使得最小的出现在最前面,那么我们就考虑用堆维护,倒序建边。

如果我们正序建边,很有可能我们选取了一个点之后再向下走发现了一个更小的点,而且这个更小的点还是可以放在前面的。而如果倒序建边,小的就一定会后出现,出现时大的已经出现过。那么我们就用栈来表示,可以确定这一方案是最优的。

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<queue>
 5 #include<stack>
 6 #include<iostream>
 7 #include<cstring>
 8 using namespace std;
 9 const int maxn=100005;
10 template<class T>
11 void clear(T &x)
12 {
13     T tmp;swap(x,tmp);
14 }
15 struct node
16 {
17     int from,to,next;
18 }edge[maxn];
19 int head[maxn],tot;
20 void addedge(int u,int v)
21 {
22     edge[++tot]=(node){u,v,head[u]};head[u]=tot;
23 }
24 priority_queue<int>q;
25 stack<int>s;
26 int n,m;
27 int entrance_degree[maxn];
28 int haha()
29 {
30     freopen("dishes.in","r",stdin);
31     freopen("dishes.out","w",stdout);
32     int t;scanf("%d",&t);
33     while(t--)
34     {
35         memset(entrance_degree,0,sizeof(entrance_degree));
36         memset(head,0,sizeof(head));clear(s);tot=0;
37         scanf("%d%d",&n,&m);
38         for(int i=1;i<=m;i++)
39         {
40             int x,y;scanf("%d%d",&x,&y);
41             addedge(y,x);entrance_degree[x]++;
42         }
43         int cnt=0;
44         for(int i=1;i<=n;i++)
45             if(!entrance_degree[i])q.push(i);
46         while(!q.empty())
47         {
48             int l=q.top();q.pop();
49             s.push(l);cnt++;
50             for(int i=head[l];i;i=edge[ i].next)
51             {
52                 int v=edge[i].to;
53                 entrance_degree[v]--;
54                 if(!entrance_degree[v])q.push(v);
55             }
56         }
57         if(cnt!=n)puts("Impossible!");
58         else 
59         {
60             while(!s.empty())
61             {
62                 printf("%d ",s.top());
63                 s.pop();
64             }
65             puts("");
66         }
67     }
68 }
69 int sb=haha();
70 int main(){;}
cogs1958

 

以上是关于cogs1958 菜肴制作 拓扑排序的主要内容,如果未能解决你的问题,请参考以下文章

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

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

bzoj4010: [HNOI2015]菜肴制作(拓扑排序+贪心+堆)

7-4 试题 H:菜肴制作 (20 分)拓扑排序

菜肴制造(拓扑排序)

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