bzoj 2535 & bzoj 2109 航空管制 —— 贪心+拓扑序
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535
https://www.lydsy.com/JudgeOnline/problem.php?id=2109
这个题,如果正着考虑,也就是先考虑放在前面的再考虑放在后面的,决策时会有矛盾;
也就是,如果要求 pos[a] < pos[b],则先考虑放 a,因为许多点放在 a 后面,所以 a 尽量往前放可以给它们留出空位;
但又有限制最晚起飞时间,那么先考虑的 a 应该尽量放在靠近它最晚起飞时间的地方,以免后面的点无法满足起飞时间的限制;
于是尽量往前放和尽量往后放形成了矛盾,无法决策;
所以需要转化一个限制,不妨对于 pos[a] < pos[b],先决策 b;
于是两个限制合起来的要求就都变成尽量往后放了(真神奇);
所以我们就这样倒着做,一定能得到合法的序列;
然后考虑每个点的可能最前位置,其实就是做的过程中把这个点以及它限制的点都暂时去掉,让其他点放好,那么不能再放的时候就意味着只有放上这个点才能继续,这时这个点按刚才做法找到的位置就是它的最前位置(其他点已经尽量把它的可行位置挤到前面了);
注意放点位置是最晚起飞时间和限制它的点的起飞时间取 min 的!
注意答案是起飞序列!而不是每个点的起飞位置!
如果用 set 找某位置前面第一个空位会很慢,还是并查集好。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
using namespace std;
int const xn=,xm=;
int n,m,hd[xn],ct,to[xm],nxt[xm],deg[xn],tmp[xn],ans[xn],d[xn],mn[xn];
struct N{
int v,id;
N(int v=,int i=):v(v),id(i) {}
};
queue<int>q;
set<int>st;
set<int>::iterator it;
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void topo(int nw)
{
for(int i=;i<=n;i++)
{
mn[i]=min(n,d[i]); tmp[i]=deg[i];
if(!tmp[i]&&i!=nw)q.push(i);
}
while(q.size())
{
int x=q.front(); q.pop();
it=st.lower_bound(n-mn[x]+);
int tim=*it;
//ans[x]=n-tim+1; //!!!
ans[n-tim+]=x;
st.erase(tim);
for(int i=hd[x],u;i;i=nxt[i])
{
if((u=to[i])==nw)continue;
tmp[u]--; mn[u]=min(mn[u],mn[x]);//!!
if(!tmp[u])q.push(u);
}
}
}
int solve(int x)
{
st.clear();
for(int i=;i<=n;i++)st.insert(i);
topo(x);
it=st.lower_bound(n-d[x]+);
return n-*it+;
}
int main()
{
n=rd(); m=rd();
for(int i=;i<=n;i++)d[i]=rd(),st.insert(i);
for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(y,x),deg[x]++;
topo();
for(int i=;i<=n;i++)printf("%d ",ans[i]); puts("");
for(int i=;i<=n;i++)printf("%d ",solve(i)); puts("");
return ;
}
set
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int const xn=,xm=;
int n,m,hd[xn],ct,to[xm],nxt[xm],deg[xn],tmp[xn],ans[xn],d[xn],mn[xn];
int fa[xn],q[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return f?ret:-ret;
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void topo(int nw)
{
int cnt=;
for(int i=;i<=n;i++)
{
mn[i]=min(n,d[i]); tmp[i]=deg[i]; fa[i]=i;
if(!tmp[i]&&i!=nw)q[++cnt]=i;
}
while(cnt)
{
int x=q[cnt--]; int tim=find(mn[x]);
ans[tim]=x; fa[tim]=tim-;
for(int i=hd[x],u;i;i=nxt[i])
{
if((u=to[i])==nw)continue;
tmp[u]--; mn[u]=min(mn[u],mn[x]);//!!
if(!tmp[u])q[++cnt]=u;
}
}
}
int solve(int x)
{
topo(x); return find(d[x]);
}
int main()
{
n=rd(); m=rd();
for(int i=;i<=n;i++)d[i]=rd();
for(int i=,x,y;i<=m;i++)x=rd(),y=rd(),add(y,x),deg[x]++;
topo();
for(int i=;i<=n;i++)printf("%d ",ans[i]); puts("");
for(int i=;i<=n;i++)printf("%d ",solve(i)); puts("");
return ;
}
bzoj 2535 & bzoj 2109 航空管制 —— 贪心+拓扑序的更多相关文章
- BZOJ 2535: [Noi2010]Plane 航空管制2
Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上 ...
- [BZOJ2109][NOI2010]航空管制(贪心+拓扑)
2109: [Noi2010]Plane 航空管制 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1227 Solved: 510[Submit][ ...
- bzoj 2535: [Noi2010]Plane 航空管制2【拓扑排序+堆】
有个容易混的概念就是第一问的答案不是k[i]字典序最小即可,是要求k[i]大的尽量靠后,因为这里前面选的时候是对后面有影响的(比如两条链a->b c->d,ka=4,kb=2,kc=3,k ...
- bzoj 2535 && bzoj 2109 [Noi2010]Plane 航空管制——贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535 https://www.lydsy.com/JudgeOnline/problem.p ...
- 2109&2535: [Noi2010]Plane 航空管制 - BZOJ
Description世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上, ...
- BZOJ 2109 航空管制(拓扑排序+贪心)
绝世好题啊.. 题意:给出一个DAG,和每个点要求出现在这个DAG里面的拓扑排序的位置<=ti,求出所有可能的拓扑排序里面每个点出现的位置的最小值. 正着做不好做,考虑反着做,建立这个图的反图. ...
- BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)
题意 题目链接 Sol 非常妙的一道题. 首先不难想到拓扑排序,但是直接对原图按\(k\)从小到大拓扑排序是错的.因为当前的\(k\)大并不意味着后面的点\(k\)也大 但是在反图上按\(k\)从大到 ...
- BZOJ.2109.[NOI2010]航空管制(拓扑 贪心)
题目链接 双倍经验(没有第一问) \(Description\) \(Solution\) 第一问拓扑排序即可. 第二问,即让一个元素在拓扑序中尽量靠前,好像不好做. 但是可以让一个元素出现尽量靠后. ...
- bzoj 2109: [Noi2010]Plane 航空管制
Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...
随机推荐
- 九度OJ 1356:孩子们的游戏(圆圈中最后剩下的数) (约瑟夫环)
时间限制:10 秒 内存限制:32 兆 特殊判题:否 提交:1333 解决:483 题目描述: 每年六一儿童节,JOBDU都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为JOBDU的资深 ...
- python-2 什么是函数
函数是什么? 定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可 特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 形参变量只有在被调用时才 ...
- mysql语句优化技巧
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引.2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引 ...
- 小程序真机GET请求出现406错误
问题:微信开发模拟器请求成功,获得数据,但是在真机上出现406请求错误,无法获得请求结果 原因:真机微信小程序的请求头与模拟器不同 怎么发现的:在请求头强制添加Accept即可解决 修复:在请求Hea ...
- iOS 代码延迟执行
1. [NSTread sleepForTimeInterval:0.8f] 这个方法 实际效果 好比打断点 等你再恢复断点执行 2. [self performSelector:@selector ...
- Python 3 接口与归一化设计
一.接口与归一化设计: 1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大地降低了使用者的使用难度. 2.归一化使得高层的外部使用者可以不加区分的处理所有接口兼 ...
- 第一篇、javascript变量和循环
一.代码存放位置 理论上放在body和head中都可以,但是推荐放在body代码块底部,因为Html代码是从上到下执行,如果Head中的js代码耗时严重,就会导致用户长时间无法看到页面,如果放置在bo ...
- 日期类(C++实现)
//-------------------------------------------------------------------------- /* **功能:实现日期的简单操作 ** ** ...
- 【反思】一个价值两天的BUG,无论工作还是学习C语言的朋友都看看吧!
博文原创,转载请联系博主! 使用C语言也有两个年头了,BUG写出来过不少,也改过不少BUG.但是偏偏就是有这么一个BUG让我手头的项目停工了两天,原因从百度找到谷歌,资料从MAN手册找到RFC也没有找 ...
- 次小生成树 POJ 2728
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>us ...