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总时限可以过
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.
后来懂了用链表写,听起来蛮简单就写了一个
1 const 2 maxn=2020; 3 maxm=10010; 4 var 5 first,k,d,di,head,suc,ans: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 procedure merge(x,y:longint); 19 begin 20 if head[x]=0 then 21 begin 22 head[x]:=head[y]; 23 exit; 24 end; 25 x:=head[x]; 26 while suc[x]<>0 do x:=suc[x]; 27 suc[x]:=head[y]; 28 end; 29 30 function time(x:longint):longint; 31 var 32 i,v:longint; 33 begin 34 for i:=1 to n do di[i]:=d[i]; 35 for i:=1 to n do head[i]:=0; 36 for i:=1 to n do 37 if (d[i]=0) and (i<>x) then 38 begin 39 suc[i]:=head[k[i]]; 40 head[k[i]]:=i; 41 end; 42 time:=n; 43 while true do 44 begin 45 if head[time]=0 then exit; 46 i:=first[head[time]]; 47 head[time]:=suc[head[time]]; 48 while i<>0 do 49 begin 50 dec(di[last[i]]); 51 if (di[last[i]]=0) and (last[i]<>x) then 52 begin 53 if k[last[i]]<time then v:=k[last[i]] 54 else v:=time; 55 suc[last[i]]:=head[v]; 56 head[v]:=last[i]; 57 end; 58 i:=next[i]; 59 end; 60 merge(time-1,time); 61 dec(time); 62 end; 63 end; 64 65 procedure work; 66 var 67 i,t,v:longint; 68 begin 69 for i:=1 to n do di[i]:=d[i]; 70 for i:=1 to n do head[i]:=0; 71 for i:=1 to n do 72 if d[i]=0 then 73 begin 74 suc[i]:=head[k[i]]; 75 head[k[i]]:=i; 76 end; 77 t:=n; 78 while t>0 do 79 begin 80 ans[t]:=head[t]; 81 i:=first[head[t]]; 82 head[t]:=suc[head[t]]; 83 while i<>0 do 84 begin 85 dec(di[last[i]]); 86 if di[last[i]]=0 then 87 begin 88 if k[last[i]]<t then v:=k[last[i]] 89 else v:=t; 90 suc[last[i]]:=head[v]; 91 head[v]:=last[i]; 92 end; 93 i:=next[i]; 94 end; 95 merge(t-1,t); 96 dec(t); 97 end; 98 end; 99 100 procedure main; 101 var 102 i,x,y:longint; 103 begin 104 read(n,m); 105 for i:=1 to n do read(k[i]); 106 for i:=1 to m do 107 begin 108 read(x,y); 109 insert(y,x); 110 end; 111 work; 112 for i:=1 to n-1 do write(ans[i],' '); 113 writeln(ans[n]); 114 for i:=1 to n-1 do write(time(i),' '); 115 write(time(n)); 116 end; 117 118 begin 119 main; 120 end.