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 1333:考研海报 (区间操作)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:738 解决:299 题目描述: sun是万千考研学子中的一员,他每天过着三点一线的生活. 学校里有一个公告栏,他每天都看到上面张贴着各种考研 ...
- iOS 运行时详解
注:本篇文章转自:http://www.jianshu.com/p/adf0d566c887 一.运行时简介 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行 ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)
连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...
- Jquery点击事件出发顺序
鼠标点击触发事件执行顺序: mouse down -> mouse up -> click 键盘点击出发事件执行顺序: 点击后马上抬起:key down -> key press - ...
- Android动画效果animation
1.Tween 根据指定动画开始和结束时的对象属性(位置.Alpha值(透明度).大小.角度等)以及动画播放的时间长度生成动画: 2.Frame 指定每一帧所播放的图片和时间长度. 建立动画的方法 ...
- Java内部类(转发:)
内部类是指在一个外部类的内部再定义一个类.类名不需要和文件夹相同. 内部类分为: 成员内部类.局部内部类.静态嵌套类.匿名内部类 . 1.成员内部类 成员内部类是最普通的内部类,它的定义为位于另一个类 ...
- 错误解决Error configuring application listener of class org.springframework.web.util.Log4jConfigListener(转发)
Spring MVC-----maven项目导入后启动tomcat出现如下错误 参考:http://blog.csdn.net/itlionwoo/article/details/17523371 解 ...
- Lattice绘图
lattice包提供了用于可视化单变量和多变量数据的一整套图形系统.许多用户转向使用lattice包是因为它能很容易地生成网格图形.网格图形能够展示变量的分布或变量之间的关系. 例:data(mtca ...
- 中国移动OnetNet云平台 GET指令使用
GET /devices//datastreams/KEY HTTP/1.1 Host: api.heclouds.com api-key: pmWLtnkDBSreKfvg7GsClUXdXa4A ...
- inline-block元素的4px空白间距解决方案
http://www.jb51.net/css/68785.html inline-block元素的4px空白间距解决方案