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表示很不满意. 在这次来烟台的 ...
随机推荐
- 前端开发中js变量定义及命名的规范建议
关于变量定义及命名 现在谈谈关于变量及方法等的命名,没有硬性规定,但为了规范,遵循一些约定还是很有必要的. 变量定义:好的做法是把将要使用的变量名用一个var关键字一并定义在代码开头,变量名间用逗号隔 ...
- 关于mac上的maven
1 mac上的maven的JAVA_HOME mac上maven的JAVA_HOME不是环境变量的JAVA_HOME,而是~/.mavenrc中的JAVA_HOME. 2 彻底解决mac上使用mvn ...
- 加密php源代码
<?php function RandAbc($length = "") { //返回随机字符串 $str = "ABCDEFGHIJKLMNOPQRSTUVWXY ...
- 为system对象添加扩展方法
////扩展方法类:必须为非嵌套,非泛型的静态类 public static class DatetimeEx { //通过this声明扩展的类,这里给DateTime类扩展一个Show方法,只有一个 ...
- GitHub提示 Error: Key already in use解决办法
GitHub提示 Error: Key already in use解决办法GitHub提示 Error: Key already in use解决办法2014年09月05日 ⁄ 综合 ⁄ 共 290 ...
- 请简单介绍一下Spring
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的.框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架. Spring ...
- zabbix实现mysql数据库的监控(一)
zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案.它能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问 ...
- android电池(五):电池 充电IC(PM2301)驱动分析篇【转】
本文转载自:http://blog.csdn.net/xubin341719/article/details/8970363 android充电这块,有的电源管理芯片内部包含充电管理,如s5pv210 ...
- 在webBrowser中取Cookie的方法
在很多情况下我们会使用间进程的webBrowser去实现一些网页的请求和抓去,这个时候有部分网页是取不到Cookie的,那怎么办呢?下面我提供一个方法,应该99%的都能取到, //取当前webBrow ...
- Delphi - 数组 详解
技术交流,DH讲解. 首先我们要知道什么是数组?数组是一堆相同特性数据的一个集合,也就是每个元素的类型必须是一样的,当然在其他一些弱语法的语言里面,数组的元素可以千奇百怪. 例子: ? 1 2 3 4 ...