zoukankan      html  css  js  c++  java
  • BZOJ 4010 菜肴制作

    Description

    知名美食家小A被邀请至ATM 大酒店,为其品评菜肴。
    ATM酒店为小A准备了(N)道菜肴,酒店按照为菜肴预估的质量从高到低给予(1)(N)的顺序编号,预估质量最高的菜肴编号为(1)。由于菜肴之间口味搭配的问题,某些菜肴必须在另一些菜肴之前制作,具体的,一共有(M)条形如“(i)号菜肴‘必须’先于(j)号菜肴制作”的限制,我们将这样的限制简写为(< i,j>)。现在,酒店希望能求出一个最优的菜肴的制作顺序,使得小 A能尽量先吃到质量高的菜肴:也就是说,((1))在满足所有限制的前提下,(1)号菜肴“尽量”优先制作;((2))在满足所有限制,(1)号菜肴“尽量”优先制作的前提下,(2)号菜肴“尽量”优先制作;((3))在满足所有限制,(1)号和(2)号菜肴“尽量”优先的前提下,(3)号菜肴“尽量”优先制作;((4))以此类推。
    (1):共(4)道菜肴,两条限制(<3,1>,<4,1>),那么制作顺序是(3,4,1,2)
    (2):共(5)道菜肴,两条限制(<5,2>,<4,3>),那么制作顺序是(1,5,2,4,3)。例(1)里,首先考虑(1),因为有限制(<3,1>)(<4,1>),所以只有制作完(3)(4)后才能制作(1),而根据((3))(3)号又应“尽量”比(4)号优先,所以当前可确定前三道菜的制作顺序是(3,4,1);接下来考虑(2),确定最终的制作顺序是(3,4,1,2)。例(2)里,首先制作(1)是不违背限制的;接下来考虑(2)时有(<5,2>)的限制,所以接下来先制作(5)再制作(2);接下来考虑(3)时有(<4,3>)的限制,所以接下来先制作(4)再制作(3),从而最终的顺序是(1,5,2,4,3)。现在你需要求出这个最优的菜肴制作顺序。无解输出“Impossible!” (不含引号,首字母大写,其余字母小写)

    Input

    第一行是一个正整数(D),表示数据组数。
    对于每组数据:
    第一行两个用空格分开的正整数(N)(M),分别表示菜肴数目和制作顺序限制的条目数。
    接下来(M)行,每行两个正整数(x,y),表示“(x)号菜肴必须先于(y)号菜肴制作”的限制。(注意:(M)条限制中可能存在完全相同的限制)

    Output

    输出文件仅包含(D)行,每行(N)个整数,表示最优的菜肴制作顺序,或者”Impossible!”表示无解(不含引号)。

    Sample Input

    3
    5 4
    5 4
    5 3
    4 2
    3 2
    3 3
    1 2
    2 3
    3 1
    5 2
    5 2
    4 3

    Sample Output

    1 5 3 4 2
    Impossible!
    1 5 2 4 3

    Hint

    (N,M le 100000,D le 3)

    Solution

    考试的时候打的(70')做法,即从小到大依次确定可以放置的最前的位置。复杂度(O(n^{2}))
    正解的做法很简单,却并不好像,好像跟NOI2010航空管制很像。
    将图反连,我们从小到大确定每个最前的位置,即在反top序中从小到大最后的位置。我们还是topsort,只是每次取出的点是所有入度为(0)的标号最大的点。这要的贪心 ,我们就可以保证编号小的尽可能的在后面。最后将top序反着输出即可。

    #include<iostream>
    #include<set>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    using namespace std;
    
    #define maxn (100010)
    int d[maxn],side[maxn],next[maxn*2],toit[maxn*2],ans[maxn],cnt,n,m;
    
    inline void add(int a,int b) { next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; ++d[b]; }
    
    struct cmp { inline bool operator ()(const int &a,const int &b) { return a>b; } };
    set <int,cmp> S;
    
    inline bool topsort()
    {
    	int tot = 0;
    	for (int i = 1;i <= n;++i) if (!d[i]) S.insert(i);
    	while (!S.empty())
    	{
    		int now = *S.begin(); S.erase(S.begin());
    		ans[++tot] = now;
    		for (int i = side[now];i;i = next[i]) if (!--d[toit[i]]) S.insert(toit[i]);
    	}
    	return tot == n;
    }
    
    int main()
    {
    	freopen("4010.in","r",stdin);
    	freopen("4010.out","w",stdout);
    	int T; scanf("%d",&T);
    	while (T--)
    	{
    		scanf("%d %d",&n,&m);
    		for (int i = 1,a,b;i <= m;++i) scanf("%d %d",&a,&b),add(b,a);
    		if (!topsort()) printf("Impossible!");
    		else for (int i = n;i;--i) printf("%d ",ans[i]);
    		puts("");	
    		memset(side,0,4*(n+1));
    		memset(d,0,4*(n+1));
    		cnt = 1;
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/mmlz/p/4448729.html
Copyright © 2011-2022 走看看