2109&2535: [Noi2010]Plane 航空管制 - BZOJ

Description
世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生。最近,小X就因为航空管制,连续两次在机场被延误超过了两小时。对此,小X表示很不满意。 在这次来烟台的路上,小 X不幸又一次碰上了航空管制。于是小 X开始思考关于航空管制的问题。 假设目前被延误航班共有 n个,编号为 1至n。机场只有一条起飞跑道,所有的航班需按某个顺序依次起飞(称这个顺序为起飞序列)。定义一个航班的起飞序号为该航班在起飞序列中的位置,即是第几个起飞的航班。 起飞序列还存在两类限制条件: ? 第一类(最晚起飞时间限制):编号为 i的航班起飞序号不得超过 ki; ? 第二类(相对起飞顺序限制):存在一些相对起飞顺序限制(a, b),表示航班 a的起飞时间必须早于航班 b,即航班 a的起飞序号必须小于航班 b 的起飞序号。 小X 思考的第一个问题是,若给定以上两类限制条件,是否可以计算出一个可行的起飞序列。第二个问题则是,在考虑两类限制条件的情况下,如何求出每个航班在所有可行的起飞序列中的最小起飞序号。
Input
第一行包含两个正整数 n和m,n表示航班数目,m表示第二类限制条件(相对起飞顺序限制)的数目。 第二行包含 n个正整数 k1, k2, „, kn。 接下来 m行,每行两个正整数 a和b,表示一对相对起飞顺序限制(a, b),其中1≤a,b≤n, 表示航班 a必须先于航班 b起飞。
Output

由两行组成。
第一行包含 n个整数,表示一个可行的起飞序列,相邻两个整数用空格分隔。
输入数据保证至少存在一个可行的起飞序列。如果存在多个可行的方案,输出任
意一个即可。
第二行包含 n个整数 t1, t2, „, tn,其中 ti表示航班i可能的最小起飞序
号,相邻两个整数用空格分隔。
Sample Input
5 5
4 5 2 5 4
1 2
3 2
5 1
3 4
3 1
Sample Output
3 5 1 4 2
3 4 1 2 1

orz VFK

首先把边反过来,k[i]变成n-k[i],整个序列反过来

就变成另一个问题了,就是点i的序号必须大于k[i],还有许多关系(a,b)表示a必须在b前面出现

然后要求一个可行序列和每个点最晚出现的时间

求可行序列就直接拓扑排序

求最晚出现时间就枚举点i

我们先把点i放一边不去管它,然后拓扑排序直到不能排为止(入度为0的点(不包括i)都不能在这个时间出现),这个就是最晚时间了

  1 const
  2     maxn=2020;
  3     maxm=10010;
  4 var
  5     k,d,first:array[0..maxn]of longint;
  6     last,next:array[0..maxm]of longint;
  7     n,m,tot:longint;
  8
  9 procedure insert(x,y:longint);
 10 begin
 11     inc(tot);
 12     last[tot]:=y;
 13     next[tot]:=first[x];
 14     first[x]:=tot;
 15     inc(d[y]);
 16 end;
 17
 18 var
 19     q,kk,du:array[0..maxn]of longint;
 20     r:longint;
 21
 22 procedure swap(var x,y:longint);
 23 var
 24     t:longint;
 25 begin
 26     t:=x;x:=y;y:=t;
 27 end;
 28
 29 procedure up(x:longint);
 30 var
 31     i:longint;
 32 begin
 33     while x>1 do
 34         begin
 35             i:=x>>1;
 36             if kk[q[x]]>kk[q[i]] then
 37                 begin
 38                     swap(q[i],q[x]);
 39                     x:=i;
 40                 end
 41             else exit;
 42         end;
 43 end;
 44
 45 procedure down(x:longint);
 46 var
 47     i:longint;
 48 begin
 49     i:=x<<1;
 50     while i<=r do
 51         begin
 52             if (i<r) and (kk[q[i+1]]>kk[q[i]]) then inc(i);
 53             if kk[q[i]]>kk[q[x]] then
 54                 begin
 55                     swap(q[i],q[x]);
 56                     x:=i;i:=x<<1;
 57                 end
 58             else exit;
 59         end;
 60 end;
 61
 62 procedure delete;
 63 begin
 64     swap(q[1],q[r]);
 65     dec(r);down(1);
 66 end;
 67
 68 function time(x:longint):longint;
 69 var
 70     i:longint;
 71 begin
 72     time:=n;r:=0;
 73     for i:=1 to n do du[i]:=d[i];
 74     for i:=1 to n do kk[i]:=k[i];
 75     for i:=1 to n do
 76         if (du[i]=0) and (i<>x) then
 77         begin
 78             inc(r);q[r]:=i;
 79             up(r);
 80         end;
 81     while r>0 do
 82         begin
 83             if time>kk[q[1]] then break;
 84             kk[q[1]]:=n+1;
 85             dec(time);
 86             i:=first[q[1]];
 87             while i<>0 do
 88                 begin
 89                     dec(du[last[i]]);
 90                     if (du[last[i]]=0) and (last[i]<>x) then
 91                     begin
 92                         inc(r);q[r]:=last[i];
 93                         up(r);
 94                     end;
 95                     i:=next[i];
 96                 end;
 97             delete;
 98         end;
 99     if du[x]<>0 then exit(-1);
100 end;
101
102 var
103     ans:array[0..maxn]of longint;
104
105 procedure work;
106 var
107     i,cnt:longint;
108 begin
109     r:=0;cnt:=n;
110     for i:=1 to n do kk[i]:=k[i];
111     for i:=1 to n do du[i]:=d[i];
112     for i:=1 to n do
113         if du[i]=0 then
114         begin
115             inc(r);q[r]:=i;
116             up(r);
117         end;
118     while r>0 do
119         begin
120             ans[cnt]:=q[1];
121             dec(cnt);
122             i:=first[q[1]];
123             kk[q[1]]:=n+1;
124             while i<>0 do
125                 begin
126                     dec(du[last[i]]);
127                     if du[last[i]]=0 then
128                     begin
129                         inc(r);q[r]:=last[i];
130                         up(r);
131                     end;
132                     i:=next[i];
133                 end;
134             delete;
135         end;
136     for i:=1 to n do
137         if i<n then write(ans[i],‘ ‘)
138         else writeln(ans[i]);
139 end;
140
141 procedure main;
142 var
143     i,x,y:longint;
144 begin
145     read(n,m);
146     for i:=1 to n do read(k[i]);
147     for i:=1 to m do
148         begin
149             read(x,y);
150             insert(y,x);
151         end;
152     work;
153     for i:=1 to n do
154         if i<n then write(time(i),‘ ‘)
155         else write(time(i));
156 end;
157
158 begin
159     main;
160 end.

2109&2535: [Noi2010]Plane 航空管制 - BZOJ

时间: 2024-08-23 23:59:16

2109&2535: [Noi2010]Plane 航空管制 - BZOJ的相关文章

Bzoj2535 [Noi2010]Plane 航空管制2

2535: [Noi2010]Plane 航空管制2 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 722  Solved: 456 Description 世 博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示 很不满意. 在这次来烟台的路上,小 X不幸又一次碰上了航空管制.于是小 X开始思考关于航空管制的问题. 假

[Noi2010]Plane 航空管制 贪心

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 2100 #define M 11000 int t[N]; int n,m; int dp[N]; int ru[N],op[N]; int e[N],ne[M],v[M]; int nn,been1[N],been2[N]; int q[N],he

bzoj 2109: [Noi2010]Plane 航空管制

Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的路上,小 X不幸又一次碰上了航空管制.于是小 X开始思考 关于航空管制的问题. 假设目前被延误航班共有 n个,编号为 1至n.机场只有一条起飞跑道,所 有的航班需按某个顺序依次起飞(称这个顺序为起飞序列).定义一个航班的起 飞序号为该航班在起飞序列中的位置,即是第几个起飞的航班. 起飞序列还存在两类

BZOJ2109 [Noi2010]Plane 航空管制

Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的路上,小 X不幸又一次碰上了航空管制.于是小 X开始思考 关于航空管制的问题. 假设目前被延误航班共有 n个,编号为 1至n.机场只有一条起飞跑道,所 有的航班需按某个顺序依次起飞(称这个顺序为起飞序列).定义一个航班的起 飞序号为该航班在起飞序列中的位置,即是第几个起飞的航班. 起飞序列还存在两类

bzoj 2535 &amp;&amp; bzoj 2109 [Noi2010]Plane 航空管制——贪心

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535 https://www.lydsy.com/JudgeOnline/problem.php?id=2109 考虑按拓扑序决策,发现不太行:主要是一种情况:虽然自己的 k[ ] 靠后,但自己限制的点的 k[ ] 靠前. 这样的话,自己应该尽量往前放:但为了别的点的这种情况,自己又应该尽量往后放,所以无法决策了. 发现这种情况主要和后面的点是否紧急有关.所以就是虽然拓扑序是那样的,但可以

BZOJ2109 NOI2010 Plane 航空管制 拓扑排序

题意:给定两种限制:1.编号为i的航班必须在ki+1之前起飞  2.(a,b)表示a必须在b之前起飞.求:1.一个合法起飞序列  2.每个航班在所有合法起飞顺序中,最早的起飞时间.问题保证有解 题解:首先按照第二个限制条件建图,那么第一问随便跑一个拓扑序就好,关键在第二问,我们枚举每一个飞机,假定该飞机不存在,不断往拓扑序中加点,直到没法再加点(不存在一个空的位置t满足存在一个节点i满足t∈[N-ki+1,N])为止,这样求出来的位置就是答案. #include <cstdio> #inclu

BZOJ 2535 Plane 航空管制2

http://www.lydsy.com/JudgeOnline/problem.php?id=2535 思路:对于1,我们只需要每个点比前驱大就可以了,然后满足尽量优. 对于第二问,我们先求出这个点前驱有几个,记为ans,cnt=ans 每访问一个未访问的点,cnt++ 然后对于后面的点从少往大排,若有k>ans,那么一定在我们当前处理这个点前面,ans++ 若有k<=cnt,说明要i放在这个点的后面,因此ans=k+1 记得不要省方便add(read(),read()),好像会出错. 1

bzoj 2109 &amp; 2535 航空管制 题解

[] [分析]真的是一道贪心好题.开始我以为是一道大水题.建立拓扑图后(没环就是方便!),直接把最外层设定序号为1,第二层为2,bfs下去即可...结果发现:飞行序号不能相同...于是开始想. 先考虑第一个问题:打印一个合法序列.我开始是这么想的: 观察每个飞机的最晚飞行序号Ki,因为必定有解,所以我们可以让它的序号就是Ki.然后用它的时间去更新前面的时间(图可以反向建立).应该可以维护一个大根堆,每次挑出最大的一个进行处理. [简易代码] memset(T,0x7f,sizeof(T)); f

NOI2010航空管制

2008: [Noi2010]航空管制 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 31  Solved: 0[Submit][Status] Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上,小X不幸又一次碰上了航空管制.于是小X开始思考关于航空管制的问题. 假设目前被延误航班共有n个,编号为