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)都不能在这个时间出现),这个就是最晚时间了

我懒,用堆写的,实际是过不去的,bzoj总时限可以过

 const
maxn=;
maxm=;
var
k,d,first:array[..maxn]of longint;
last,next:array[..maxm]of longint;
n,m,tot:longint; procedure insert(x,y:longint);
begin
inc(tot);
last[tot]:=y;
next[tot]:=first[x];
first[x]:=tot;
inc(d[y]);
end; var
q,kk,du:array[..maxn]of longint;
r:longint; procedure swap(var x,y:longint);
var
t:longint;
begin
t:=x;x:=y;y:=t;
end; procedure up(x:longint);
var
i:longint;
begin
while x> do
begin
i:=x>>;
if kk[q[x]]>kk[q[i]] then
begin
swap(q[i],q[x]);
x:=i;
end
else exit;
end;
end; procedure down(x:longint);
var
i:longint;
begin
i:=x<<;
while i<=r do
begin
if (i<r) and (kk[q[i+]]>kk[q[i]]) then inc(i);
if kk[q[i]]>kk[q[x]] then
begin
swap(q[i],q[x]);
x:=i;i:=x<<;
end
else exit;
end;
end; procedure delete;
begin
swap(q[],q[r]);
dec(r);down();
end; function time(x:longint):longint;
var
i:longint;
begin
time:=n;r:=;
for i:= to n do du[i]:=d[i];
for i:= to n do kk[i]:=k[i];
for i:= to n do
if (du[i]=) and (i<>x) then
begin
inc(r);q[r]:=i;
up(r);
end;
while r> do
begin
if time>kk[q[]] then break;
kk[q[]]:=n+;
dec(time);
i:=first[q[]];
while i<> do
begin
dec(du[last[i]]);
if (du[last[i]]=) and (last[i]<>x) then
begin
inc(r);q[r]:=last[i];
up(r);
end;
i:=next[i];
end;
delete;
end;
if du[x]<> then exit(-);
end; var
ans:array[..maxn]of longint; procedure work;
var
i,cnt:longint;
begin
r:=;cnt:=n;
for i:= to n do kk[i]:=k[i];
for i:= to n do du[i]:=d[i];
for i:= to n do
if du[i]= then
begin
inc(r);q[r]:=i;
up(r);
end;
while r> do
begin
ans[cnt]:=q[];
dec(cnt);
i:=first[q[]];
kk[q[]]:=n+;
while i<> do
begin
dec(du[last[i]]);
if du[last[i]]= then
begin
inc(r);q[r]:=last[i];
up(r);
end;
i:=next[i];
end;
delete;
end;
for i:= to n do
if i<n then write(ans[i],' ')
else writeln(ans[i]);
end; procedure main;
var
i,x,y:longint;
begin
read(n,m);
for i:= to n do read(k[i]);
for i:= to m do
begin
read(x,y);
insert(y,x);
end;
work;
for i:= to n do
if i<n then write(time(i),' ')
else write(time(i));
end; begin
main;
end.

后来懂了用链表写,听起来蛮简单就写了一个

 const
maxn=;
maxm=;
var
first,k,d,di,head,suc,ans:array[..maxn]of longint;
last,next:array[..maxm]of longint;
n,m,tot:longint; procedure insert(x,y:longint);
begin
inc(tot);
last[tot]:=y;
next[tot]:=first[x];
first[x]:=tot;
inc(d[y]);
end; procedure merge(x,y:longint);
begin
if head[x]= then
begin
head[x]:=head[y];
exit;
end;
x:=head[x];
while suc[x]<> do x:=suc[x];
suc[x]:=head[y];
end; function time(x:longint):longint;
var
i,v:longint;
begin
for i:= to n do di[i]:=d[i];
for i:= to n do head[i]:=;
for i:= to n do
if (d[i]=) and (i<>x) then
begin
suc[i]:=head[k[i]];
head[k[i]]:=i;
end;
time:=n;
while true do
begin
if head[time]= then exit;
i:=first[head[time]];
head[time]:=suc[head[time]];
while i<> do
begin
dec(di[last[i]]);
if (di[last[i]]=) and (last[i]<>x) then
begin
if k[last[i]]<time then v:=k[last[i]]
else v:=time;
suc[last[i]]:=head[v];
head[v]:=last[i];
end;
i:=next[i];
end;
merge(time-,time);
dec(time);
end;
end; procedure work;
var
i,t,v:longint;
begin
for i:= to n do di[i]:=d[i];
for i:= to n do head[i]:=;
for i:= to n do
if d[i]= then
begin
suc[i]:=head[k[i]];
head[k[i]]:=i;
end;
t:=n;
while t> do
begin
ans[t]:=head[t];
i:=first[head[t]];
head[t]:=suc[head[t]];
while i<> do
begin
dec(di[last[i]]);
if di[last[i]]= then
begin
if k[last[i]]<t then v:=k[last[i]]
else v:=t;
suc[last[i]]:=head[v];
head[v]:=last[i];
end;
i:=next[i];
end;
merge(t-,t);
dec(t);
end;
end; procedure main;
var
i,x,y:longint;
begin
read(n,m);
for i:= to n do read(k[i]);
for i:= to m do
begin
read(x,y);
insert(y,x);
end;
work;
for i:= to n- do write(ans[i],' ');
writeln(ans[n]);
for i:= to n- do write(time(i),' ');
write(time(n));
end; begin
main;
end.

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

  1. BZOJ 2535: [Noi2010]Plane 航空管制2

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上 ...

  2. bzoj 2535: [Noi2010]Plane 航空管制2【拓扑排序+堆】

    有个容易混的概念就是第一问的答案不是k[i]字典序最小即可,是要求k[i]大的尽量靠后,因为这里前面选的时候是对后面有影响的(比如两条链a->b c->d,ka=4,kb=2,kc=3,k ...

  3. bzoj 2109: [Noi2010]Plane 航空管制

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...

  4. BZOJ2109: [Noi2010]Plane 航空管制

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频 发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此, 小X表示很不满意. 在这次来烟台的 ...

  5. BZOJ2535 [Noi2010]Plane 航空管制2

    Description 世博期间,上海的航空客运量大大超过了平时,随之而来的航空管制也频频发生.最近,小X就因为航空管制,连续两次在机场被延误超过了两小时.对此,小X表示很不满意. 在这次来烟台的路上 ...

  6. bzoj 2535 && bzoj 2109 [Noi2010]Plane 航空管制——贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2535 https://www.lydsy.com/JudgeOnline/problem.p ...

  7. BZOJ2535: [Noi2010]Plane 航空管制2(拓扑排序 贪心)

    题意 题目链接 Sol 非常妙的一道题. 首先不难想到拓扑排序,但是直接对原图按\(k\)从小到大拓扑排序是错的.因为当前的\(k\)大并不意味着后面的点\(k\)也大 但是在反图上按\(k\)从大到 ...

  8. BZOJ2535 [Noi2010]Plane 航空管制 【贪心 + 堆】

    题目链接 BZOJ2535 题解 航班之间的关系形成了一个拓扑图 而且航班若要合法,应尽量早出发 所以我们逆拓扑序选点,能在后面出发的尽量后面出发,不会使其它点变得更劣,容易知是正确的 第二问只需枚举 ...

  9. 【BZOJ2109/2535】【NOI2010】航空管制(贪心)

    [BZOJ2109/2535][NOI2010]航空管制(贪心) 题面 BZOJ2109 BZOJ2535 题解 很好玩的一道题目 先看第一问,显然是要找一个合法的拓扑排序的序列. 直接拓扑排序,把队 ...

随机推荐

  1. SQL事务隔离级别

    数据库是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以下几种不确定情况. 更新丢失(Lost update) 两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修 ...

  2. Xcode中使用插件

    有两种添加插件的方法.推荐第二种 一.就是在Github上找到你要安装的插件,然后在Xcode完全退出后,打开你要安装的插件,编译就行了,然后完全退出后,重新打开Xcode,会出来这个图 点击load ...

  3. 【学习笔记】【C语言】选择结构-if

    1.if的第1种结构 if(条件) {     语句1;     语句2;     ...... } 如果if右边小括号()中的条件成立,也就是为“真”时,就会执行大括号{}中的语句: 如果条件为假, ...

  4. ZLComboBox自定义控件开发详解

    [引言]距离上一回写博客已经有一些时日了,之前的爱莲iLinkIT系列主要是讲解了如何用NodeJS来实现一个简单的“文件传送”软件,属于JavaScript中在服务器端的应用. 今天,我们就回归到J ...

  5. [javascript|基本概念|Unll]学习笔记

    Uull类型的值:null(只有一个)|空对象指针|typeof操作符返回object 作用:一般用于对即将保存对象但不知具体对象的引用 特殊:null == undefined --> tru ...

  6. 最强Android模拟器genymotion的安装与配置

    Android开发人员都知道,原生的模拟器启动比较慢,操作起来也不流畅,还会出现莫名的问题.当然很多人都会选择直接使用android手机来开发,但是有时候需要在投影仪上演示程序的时候手机不太好做到吧. ...

  7. Python线性时间排序——桶排序、基数排序与计数排序

    1. 桶排序 1.1 范围为1-M的桶排序 如果有一个数组A,包含N个整数,值从1到M,我们可以得到一种非常快速的排序,桶排序(bucket sort).留置一个数组S,里面含有M个桶,初始化为0.然 ...

  8. 每日一“酷”之bisect

    作用:维护有序列表,而不必在每次想列表增加一个元素时调用sort排序 bisect 模块实现了一个算法用于向列表中插入元素,同时仍保持列表有序.有些情况下,这比反复对一个了表序列更高效,另外也比构建一 ...

  9. SQL Server 2014 Always on ON Microsoft Azure New Portal(1)

    以前假如需要在Azure IaaS 创建的SQL Server AlwaysOn 需要参考以下的步骤 From the MVPs: SQL Server High Availability in Wi ...

  10. ActiveMQ之selector的用法

    前面的例子中创建一个消息消费者使用的是: sesssion.createConsumer(destination) 另外,还提供了另一种方式: sesssion.createConsumer(dest ...