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


    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
  • 相关阅读:
    CocoaPods的安装和使用
    HTTP协议(一)
    iOS常用设计模式之观察者模式
    git使用方法
    关于网络开发中XML的使用
    观察者模式的具体应用——通知(notification)机制和KVO(KeyValueObserving)机制
    HTTP协议(二)之HTTP请求
    iOS常用设计模式之委托模式
    x ^y mod m
    Problem A: 速算24点
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3792999.html
Copyright © 2020-2023  润新知