【题解】[HNOI2015]菜肴制作(贪心+topo序)

题意:请你构造一个排列\(p[i]\)使得对于数组\(arc[i]=p[i]\)的字典序最小,并且对于给定的有序数对\((u,v)\)保证你给出的排列\(u\)早于\(v\)出现。

结论:\(u->v\)连边的反图的最大拓扑序的reverse

证明:这个排列的合法性是显然的,因为是topo序。下证不存在一个更优排列\(p[]\)使得\(arc[]\)字典序更小。

考虑反证,假设存在一个更优排列\(p'[]\)比我们如上算法得到的\(p[]\)要更优。

不妨假设\(p\not = p'\)

下证\(r'=\mathrm{reverse}(p')\)必然是反图拓扑序的一组解,否则\(p'\)必不是一组合法解。

证明:显然

由于\(p'\)满足了题意条件,也就是满足\(u\)在\(v\)前出现,那么将\(r'\),就满足\(u\)在\(v\)后出现。所以\(r'\)将是一组反图拓扑序合法解。

所以\(r'\)可以跑反图拓扑序得到,设\(r=\mathrm{reverse}(p)\)。设\(\min i,\mathrm{s.t.} arc[i]>arc'[i]\),那么肯定更优

不会证明了记住套路吧

这是一类题,要你通过构造排列\(p\)使得\(\mathrm{arc}\ p\)的字典序最小。

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define DEBUG(s)
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(!isdigit(c))f|=c==45,c=getchar();
while(isdigit(c)) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
} vector<vector<int> > e;
vector<int> dr,ans;
priority_queue<int,vector<int>,greater<int> > q;
int n,m;
inline void add(const int&fr,const int&to){
//DEBUG(fr); DEBUG(to);
e[to].push_back(fr); ++dr[fr];
} inline void work(){
n=qr(); m=qr();
e.clear(); e.resize(n+1); dr.clear(); dr.resize(n+1); ans.clear();
//DEBUG(n); DEBUG(m);
for(int t=1;t<=n;++t) if(dr[t]) cerr<<"wa";
for(int t=1,x,y;t<=m;++t){
x=qr(),y=qr();
add(y,x);
}
for(int t=1;t<=n;++t) if(!dr[t]) q.push(t);
while(q.size()){
int now=q.top();
q.pop();
//DEBUG(now);
ans.push_back(now);
for(const auto&t:e[now])
if(--dr[t]==0)
q.push(t);
}
if((int)ans.size()!=n) return puts("Impossible!"),void();
for(const auto&t:ans)
printf("%d ",t);
putchar('\n');
} int main(){
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
#endif
//freopen("debug.out","w",stderr);
int T=qr();
while(T--) work();
return 0;
}

最新文章

  1. 新作《ASP.NET Web API 2框架揭秘》正式出版
  2. 智能车学习(一)&mdash;&mdash; 硬件准备
  3. Duplicate Symbol链接错的原因总结和解决方法-b
  4. BZOJ 1044
  5. Java程序读取tomcat下的properties配置文件
  6. UICollectionView 集合视图用法,自定义Cell
  7. WCF创建到使用到发布
  8. github上传文件
  9. Oracle数据库应用
  10. 了解adb的基本原理
  11. rsync实现数据增量备份
  12. Struts2 转换器
  13. jboss规则引擎KIE Drools 6.3.0 Final 教程(3)
  14. Java笔记 #07# Hibernate Validator
  15. FFT 快速傅里叶变换 学习笔记
  16. linux后台运行python程序 nohup
  17. python基础提高演练(名片管理系统的开发)
  18. innobackupex 备份 Xtrabackup 增量备份
  19. PID控制動手玩玩看
  20. (23)ajax实现上传文件的功能

热门文章

  1. CF1238E.Keyboard Purchase 题解 状压/子集划分DP
  2. 源映射错误:request failed with status 404
  3. 微信小程序下拉刷新真机无法弹回
  4. 2017年NOIP普及组复赛题解
  5. C++调用Lua编程环境搭建及测试代码示例
  6. tf.reduce_sum()函数
  7. H3C Easy IP配置举例
  8. java一维数组的声明与初始化
  9. Vue 用第三方的库去实现动画效果
  10. H3C 显示OSPF的链路状态数据库