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

我懒,用堆写的,实际是过不去的,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.
View Code

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

  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.
View Code

 

你可能感兴趣的:(ANE)