[NOI2010]航空管制(拓扑排序+贪心)
题目描述
世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生。最近,小X就因为航空管制,连续两次在机场被延误超过了两小时。对此,小X表示很不满意。
在这次来烟台的路上,小X不幸又一次碰上了航空管制。于是小X开始思考关于航空管制的问题。
假设目前被延误航班共有n个,编号为1至n。机场只有一条起飞跑道,所有的航班需按某个顺序依次起飞(称这个顺序为起飞序列)。定义一个航班的起飞序号为该航班在起飞序列中的位置,即是第几个起飞的航班。
起飞序列还存在两类限制条件:
• 第一类(最晚起飞时间限制):编号为i的航班起飞序号不得超过ki;
• 第二类(相对起飞顺序限制):存在一些相对起飞顺序限制(a, b),表示航班a的起飞时间必须早于航班b,即航班a的起飞序号必须小于航班b的起飞序号。
小X思考的第一个问题是,若给定以上两类限制条件,是否可以计算出一个可行的起飞序列。第二个问题则是,在考虑两类限制条件的情况下,如何求出每个航班在所有可行的起飞序列中的最小起飞序号。
题解
我好菜啊。。
对于第一问,我们可以倒着贪心,尽量把k大的往后放,搞一个以k为关键字的大根堆,在反图上拓扑一下就可以了,我在这想了半天,太菜了。。。
对于第二问,我们还是倒着放,和上边一样,这次我们不在堆中放i这个点,直到出现一个不合法的点出现,这时我们再加入i点就可以了。
这样的思路和这道题一样。
代码
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #define N 2002 #define M 10002 using namespace std; int k[N],n,m,tot,head[N],du[N],num,pos[N],ans[N],d[N]; inline int rd(){int x=0;char c=getchar();bool f=0;while(!isdigit(c)){if(c=='-')f=1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return f?-x:x; } struct edge{int n,to;}e[M]; inline void add(int u,int v){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;} struct node{int id;inline bool operator <(const node &b)const{return k[id]<k[b.id];} }; struct wf{int u,v;}b[M]; priority_queue<node>q; int main(){n=rd();m=rd();for(int i=1;i<=n;++i)k[i]=rd();for(int i=1;i<=m;++i){b[i].u=rd();b[i].v=rd();add(b[i].v,b[i].u);d[b[i].u]++;}memcpy(du,d,sizeof(d));for(int i=1;i<=n;++i)if(!du[i])q.push(node{i});while(!q.empty()){int u=q.top().id;q.pop();num++;pos[num]=u;for(int i=head[u];i;i=e[i].n){int v=e[i].to;if(!--du[v])q.push(node{v});}}for(int i=n;i>=1;--i)printf("%d ",pos[i]);puts("");for(int o=1;o<=n;++o){while(!q.empty())q.pop();memcpy(du,d,sizeof(d));for(int i=1;i<=n;++i)if(!du[i]&&i!=o)q.push(node{i});for(int g=n;g>=1;--g){ if(q.empty()){ans[o]=g;break;}int u=q.top().id;q.pop();if(k[u]<g){ans[o]=g;break;}for(int i=head[u];i;i=e[i].n){int v=e[i].to;if(!--du[v]&&v!=o)q.push(node{v});}}} for(int i=1;i<=n;++i)printf("%d ",ans[i]);return 0; }
转载于:https://www.cnblogs.com/ZH-comld/p/10181814.html
[NOI2010]航空管制(拓扑排序+贪心)相关推荐
- BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)
题意 题目链接 Sol 非常妙的一道题. 首先不难想到拓扑排序,但是直接对原图按\(k\)从小到大拓扑排序是错的.因为当前的\(k\)大并不意味着后面的点\(k\)也大 但是在反图上按\(k\)从大到 ...
- POJ3687拓扑排序+贪心
题意: 给你n个求,他们的重量是1-n(并不是说1号求的重量是1...),然后给你m组关系a,b,表示a的重量小于b的重量,然后让你输出满足要求的前提下每个球的重量,要求字典序最小. 思路 ...
- BZOJ 2535:NOI 2010 航空管制
[NOI2010]航空管制 题面请点上面. 首先第一问,我第一想法是把它放到一个小根堆中,然而这是不行的. 正确的思路是,把图反过来建,然后放到一个大根堆里去. 至于原因,感性理解一下,正着贪是有后效 ...
- BZOJ2535 [Noi2010]Plane 航空管制 【贪心 + 堆】
题目链接 BZOJ2535 题解 航班之间的关系形成了一个拓扑图 而且航班若要合法,应尽量早出发 所以我们逆拓扑序选点,能在后面出发的尽量后面出发,不会使其它点变得更劣,容易知是正确的 第二问只需枚举 ...
- bzoj 2109: [Noi2010]Plane 航空管制
Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...
- 每日一套codeforce集训1119E[贪心],821C[栈模拟],645D[拓扑排序]
有n种长度的棍子,长度分别为2^0 ,2 ^ 1,-,2 ^ (n-1) ,每种棍子有a[i] 种,问你能组成多少个三角形. 三角形两边之和大于第三边,而2 ^ i + 2 ^ i = 2 ^ (i+ ...
- CF思维联系--CodeForces -214C (拓扑排序+思维+贪心)
ACM思维题训练集合 Furik and Rubik love playing computer games. Furik has recently found a new game that gre ...
- BZOJ2535: [Noi2010]Plane 航空管制2
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2535 把图反向,拓扑排序一下,用并查集维护当前权值能放置的最大位置.对于第二问,就相当于我把点 ...
- LeetCode 807. 保持城市天际线 / 630. 课程表 III(贪心+优先队列)/ 851. 喧闹和富有(拓扑排序)
807. 保持城市天际线 2021.12.13 每日一题 题目描述 给你一座由 n x n 个街区组成的城市,每个街区都包含一座立方体建筑.给你一个下标从 0 开始的 n x n 整数矩阵 grid ...
最新文章
- 4*4按键扫描程序c语言,【资料】单片机4*4矩阵键盘扫描程序(c语言+汇编语言2个版本)...
- Python爬虫之selenium库使用详解
- 【转载】用 Pyinstaller 来打包 + 解决打包结果过大问题
- 前端画面-下拉后滚动
- RCP:给GEF编辑器添加网格和标尺。
- Codeforces Good Bye 2015 D. New Year and Ancient Prophecy 后缀数组 树状数组 dp
- Linux内存映射实现框架
- CMMI3认证过程总结
- 百度网盘客户端(java)版本
- VS2013创建Windows服务
- css宋体代码_css怎么设置字体为宋体
- 一份完整详细的新媒体营销推广策划方案 (微信微博等)
- ASA防火墙基本操作
- 江苏省普通话水平测试计算机评分细则,江苏省计算机辅助普通话水平测试评分细则...
- 校招详解(术语、时间、流程)
- c++中内存拷贝函数(C++ memcpy)详解
- ProxmoxVE折腾记录(一)--安装
- 苹果设备中的分辨率问题
- Linux下poky编译2
- 宋甲伟老师 5G通信服务实战专家