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 号和 2 号和 3 号菜肴“尽量”优先的前提下,4 号菜肴“尽量”优先制作;(5)以此类推。 例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,表示数据组数。

接下来是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

【样例解释】

第二组数据同时要求菜肴1先于菜肴2制作,菜肴2先于菜肴3制作,菜肴3先于
菜肴1制作,而这是无论如何也不可能满足的,从而导致无解。 
100%的数据满足N,M<=100000,D<=3。 

题解:

  强,一时还真没反应过来。

  要求把小的尽量放在前面,那么我们很确定,1的位置开始是确定的,对于1前面的,我们的目的是使其小的尽量在前面,然后……从1倒着看就是字典序最大(因为小的尽量在后面),然后对于1后面的排列,我们类比1的思路,题解就显然了。

  建立反图,拓扑字典最大序,逆向输出。

  

 #include<cstdio>
#include<queue> const int N=;
inline void GG(){
printf("Impossible!\n");
}
inline int read(){
int s=;char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(ch>=''&&ch<='')
s=s*+(ch^),ch=getchar();
return s;
}
int n,m;
std::priority_queue<int > q;
struct edges{
int v;edges *last;
}edge[N<<],*head[N];int cnt;
inline void push(int u,int v){
edge[++cnt]=(edges){v,head[u]};head[u]=edge+cnt;
}
int in[N];
int ans[N];
inline void solve (){
n=read(),m=read();
cnt=;
memset(head,,sizeof(head));
memset(in,,sizeof(in));
for(int i=,u,v;i<=m;i++){
u=read(),v=read();
if(u==v){
GG();return ;
}
push(v,u);
in[u]++;
}
int num=;
for(int i=;i<=n;i++)
if(!in[i])
q.push(i),num++;
if(!num){
GG();return ;
}
int t=n;
while(!q.empty()){
ans[t]=q.top(),q.pop();
for(edges *i=head[ans[t]];i;i=i->last){
in[i->v]--;
if(in[i->v]==)
q.push(i->v);
}
t--;
}
if(t!=){
GG();return ;
}
for(int i=;i<=n;i++)
printf("%d%c",ans[i],i<n?' ':'\n');
}
int main(){
int T=read();
while(T--)
solve();
}

【BZOJ 4010】 [HNOI2015]菜肴制作的更多相关文章

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

    题目链接: 题目 4010: [HNOI2015]菜肴制作 Time Limit: 5 Sec Memory Limit: 512 MB 问题描述 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴 ...

  2. BZOJ 4010: [HNOI2015]菜肴制作( 贪心 )

    把图反向,然后按拓扑序贪心地从大到小选, 最后输出.set比priority_queue慢... --------------------------------------------------- ...

  3. bzoj 4010 [HNOI2015]菜肴制作——贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4010 和 bzoj 2535 差不多.因为当前怎么决策与该点后面连的点的标号情况有关,所以按 ...

  4. bzoj 4010: [HNOI2015]菜肴制作

    Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予 1到N的顺序编号,预估质量最高的菜肴编号 ...

  5. bzoj 4010: [HNOI2015]菜肴制作【拓扑排序】

    也就是给定有向图,求最小字典序的拓扑序,直接用小根堆就行(或者反着建图用大根堆) #include<iostream> #include<cstdio> #include< ...

  6. 4010: [HNOI2015]菜肴制作

    拓扑排序+堆. 转自popoqqq神犇. 反向建图跑拓扑排序然后逆序输出. 为什么不能正的来呢,因为不知道选当前菜要先制作哪种菜. 逆序过来跑拓扑的话,也能保证满足限制条件编号小的在前面. 题外话:我 ...

  7. 【BZOJ】[HNOI2015]菜肴制作

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4010 要是考场上想不出,但是还是有一个分治的做法的嘛 做法就是反向连边,然后再反向输出字典 ...

  8. P3243 [HNOI2015]菜肴制作(拓扑排序)

    P3243 [HNOI2015]菜肴制作 题目误导你正着做拓扑排序,然鹅你可以手造数据推翻它.于是就只能倒着做 我们开个优先队列,每次把可填的最大的编号取出来搞,最后倒着输出拓扑序就好辣 #inclu ...

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

    [BZOJ4010][HNOI2015]菜肴制作 Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高 ...

  10. BZOJ_4010_[HNOI2015]菜肴制作_拓扑排序+贪心

    BZOJ_4010_[HNOI2015]菜肴制作_拓扑排序+贪心 Description 知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜 ...

随机推荐

  1. spiral matrix 螺旋矩阵

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  2. List内存分配

    当采用默认构造函数List<int> value = new List<int>();实例化一个List<T>对象时,.Net Framework只是在内存中申请了 ...

  3. JVM笔记8-虚拟机性能监控与故障处理工具

    1.JDK命令行工具 Java开发人员肯定都知道JDK的bin目录有“java.exe”,"javac.exe"这两个命令行工具,但并非所有程序员都了解过JDK的bin目录之中其他 ...

  4. Terminating app due to uncaught exception 'CALayerInvalid', reason: 'layer <CALayer: 0x7fda42c66e30> is a part of cycle in its layer tree'

    iOS App里面所有的View构成一个组件树,这个树里面如果有了闭环就会出现这个报错,最常见的你不小在某UIViewController里面写了这样的代码: someView.addSubView( ...

  5. Android Studio使用手记

    1.官方的Tip and Tricks:http://developer.android.com/intl/zh-cn/sdk/installing/studio-tips.html 2.项目的目录树 ...

  6. c#之多线程之为所欲为

    一 什么是多线程 1. 什么是进程?一个 exe 运行一次就会产生一个进程,一个 exe 的多个进程之 间数据互相隔离. 2. 一个进程里至少有一个线程:主线程.我们平时写的控制台程序默认就是单线程的 ...

  7. 关于H5的Canvas

    1.什么是canvas? <canvas>标签是h5新增的,通过脚本(通常是js)来绘制图形,canvas只是一个图形容器,或者说是画布. canvas可以绘制路径.图形.字以及添加图像. ...

  8. 大型三甲医院医疗体检信息管理系统源码 PEIS 体检科软件 CS

    详情请点击查看 开发环境 :VS2008 + C# + SQL2000 功能介绍: 1:设置:操作员设置   系统功能设置    用户组权限设置  公告打印设置  数据字典设置  临床类型设置  体检 ...

  9. linux内核堆栈

    一:进程的堆栈 内核在创建进程的时候,在创建task_struct的同时会为进程创建相应的堆栈.每个进程会有两个栈,一个用户栈,存在于用户空间,一个内核栈,存 在于内核空间.当进程在用户空间运行时,c ...

  10. PAT1037:Magic Coupon

    1037. Magic Coupon (25) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The magi ...