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表示很不满意. 在这次来烟台的 ...
随机推荐
- cocos2dx使用cocostudio导出的ui
local uilocal function createLayerUI() if not ui then ui=cc.Layer:create(); createLayerUI=nil; end r ...
- codeforces Gravity Flip 题解
版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...
- jQuery 中的 Deferred 和 Promises(转)
转自:http://www.css88.com/archives/4750/comment-page-1 看前首先了解:Promises/A规范,具体可以看这里,http://www.css88.co ...
- 牛客小白月赛1 C 分元宵【快速幂】
题目链接 https://www.nowcoder.com/acm/contest/85/C 思路 有 A 种 元宵馅,B 种元宵皮 所以 我们可以认为 有Q = A * B 种 元宵 有 C 张桌子 ...
- Block的详细介绍
关于block的介绍 ==ios中的内存空间分级== 栈区 存放函数参数值.局部变量.函数返回地址等,函数跳转跳转时现场保护(寄存器),这些系统都会帮我们自动实现,无需我们干预. 所以大量的局部变量, ...
- Python 3 mysql 简介安装
Python 3 mysql 简介安装 一.数据库是什么 1. 什么是数据库(DataBase,简称DB) 数据库(database,DB)是指长期存储在计算机内的,有组织,可共享的数据的集合.数据 ...
- day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包
内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...
- apache中配置php支持模块模式、cgi模式和fastcgi模式的实验
首先安装apache.mysql和php,依次顺序安装. 1.apache.mysql的安装比较简单,略过 2. php的安装,我安装的是php5.3.6内置了php-fpm,所以不需要再单独下补丁了 ...
- Codeforces 219D Choosing Capital for Treeland:Tree dp
题目链接:http://codeforces.com/problemset/problem/219/D 题意: 给你一棵树,n个节点. 树上的边都是有向边,并且不一定是从父亲指向儿子的. 你可以任意翻 ...
- html基础学习(注意点)
浏览器会自动地在块级元素(<p><h1>)的前后添加空行 当显示页面时,浏览器会移除源代码中多余的空格和空行.所有连续的空格或空行都会被算作一个空格.需要注意的是,HTML 代 ...