bzoj 2109: [Noi2010]Plane 航空管制 贪心+拓扑排序
2017-11-02 20:03
225 查看
题意
世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生。最近,小X就因为航空管制,连续两次在机场被延误超过了两小时。对此, 小X表示很不满意。 在这次来烟台的路上,小 X不幸又一次碰上了航空管制。于是小 X开始思考 关于航空管制的问题。 假设目前被延误航班共有 n个,编号为 1至n。机场只有一条起飞跑道,所 有的航班需按某个顺序依次起飞(称这个顺序为起飞序列)。定义一个航班的起 飞序号为该航班在起飞序列中的位置,即是第几个起飞的航班。 起飞序列还存在两类限制条件: 第一类(最晚起飞时间限制):编号为 i的航班起飞序号不得超过 ki; 第二类(相对起飞顺序限制):存在一些相对起飞顺序限制(a, b),表示 航班 a的起飞时间必须早于航班 b,即航班 a的起飞序号必须小于航班 b 的起飞序号。 小X 思考的第一个问题是,若给定以上两类限制条件,是否可以计算出一个 可行的起飞序列。第二个问题则是,在考虑两类限制条件的情况下,如何求出每 个航班在所有可行的起飞序列中的最小起飞序号。n≤2,000,m≤10,000。
分析
对于一个第二种限制(a,b),考虑从b向a连一条有向边。那么一个合法的序列肯定是满足拓扑序倒序的。假设我们现在要求第x辆飞机的答案,考虑把该图做拓扑排序,那么如果一个点度为0且其时间限制不小于当前时间,则该点可以被加入队列,否则就等到该点可以被使用的时候再把该点加入。
由于x要尽量靠后,那么我们就一直不使用x,知道某一时刻队列为空则该时刻即为答案。
为什么要反着建边呢?因为第一个限制限制的是最晚时间,那么如果从后往前选,就不用担心时间限制冲突的问题了。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<vector> using namespace std; const int N=2005; int n,m,cnt,last ,q ,d ,t ,degree ; struct edge{int to,next;}e[N*5]; vector<int> vec ; int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void addedge(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; } int solve(int tar) { for (int i=1;i<=n;i++) vec[i].clear(),d[i]=degree[i]; int head=1,tail=0; for (int i=1;i<=n;i++) if (!d[i]&&i!=tar) { if (t[i]==n) q[++tail]=i; else vec[t[i]].push_back(i); } int tim=n+1; while (1) { tim--; for (int i=0;i<vec[tim].size();i++) q[++tail]=vec[tim][i]; vec[tim].clear(); if (head>tail) return tim; int u=q[head];head++; for (int i=last[u];i;i=e[i].next) { d[e[i].to]--; if (!d[e[i].to]&&e[i].to!=tar) { if (t[e[i].to]>=tim) q[++tail]=e[i].to; else vec[t[e[i].to]].push_back(e[i].to); } } } } int main() { n=read();m=read(); for (int i=1;i<=n;i++) t[i]=read(); for (int i=1;i<=m;i++) { int x=read(),y=read(); addedge(y,x);degree[x]++; } for (int i=1;i<=n;i++) printf("%d ",solve(i)); return 0; }
相关文章推荐
- [拓扑排序] BZOJ 2535 [Noi2010]Plane 航空管制2 & 2109 [Noi2010]Plane 航空管制
- bzoj2109 [Noi2010]Plane 航空管制 贪心 拓补排序
- BZOJ2109: [Noi2010]Plane 航空管制 解题报告
- [BZOJ2109][NOI2010]航空管制(贪心+拓扑)
- bzoj2535 [Noi2010]Plane 航空管制2 [贪心+堆]
- [BZOJ 2109/BZOJ 2535][NOI 2010]航空管制(贪心)
- BZOJ 2535|BZOJ 2109|BZOJ 2008|NOI 2010|航空管制|拓扑排序
- bzoj 2109: [Noi2010]Plane 航空管制
- BZOJ2535 [Noi2010]Plane 航空管制 【贪心 + 堆】
- BZOJ2535: [Noi2010]Plane 航空管制2
- BZOJ2535 [Noi2010]Plane 航空管制2
- Bzoj2535 [Noi2010]Plane 航空管制2
- 2109&2535: [Noi2010]Plane 航空管制 - BZOJ
- bzoj2535: [Noi2010]Plane 航空管制
- bzoj2535 [Noi2010]航空管制
- noi 2010 航空管制 贪心
- 2535: [Noi2010]Plane 航空管制2
- BZOJ2109: [Noi2010]Plane 航空管制
- bzoj 2109: [Noi2010]Plane 航空管制
- [NOI2010]航空管制(贪心+堆)