zoukankan      html  css  js  c++  java
  • bzoj2535 [Noi2010]航空管制

    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

    正解:贪心+堆。

    表示蒟蒻的我只会做第一问,然而第二问也这么水。。

    第一问很简单,反向拓扑序+大根堆,然后从后往前依次填序号就行。

    第二问其实也不难。和第一问一样,只要我们把当前这个点卡住,不对它进行任何操作,当我们发现堆中取出的点没有办法再标号时,那这个标号就是询问点的最小标号。

    然而优先队列被卡成狗,只好改成手写堆。。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <queue>
    10 #include <stack>
    11 #include <map>
    12 #include <set>
    13 #define inf (1<<30)
    14 #define N (500010)
    15 #define il inline
    16 #define RG register
    17 #define ll long long
    18 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    19 
    20 using namespace std;
    21 
    22 struct edge{ int nt,to; }g[N];
    23 
    24 int head[N],cnt[N],d[N],k[N],a[N],b[N],Q[N],n,m,num,len;
    25 
    26 il int gi(){
    27     RG int x=0,q=1; RG char ch=getchar();
    28     while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    29     if (ch=='-') q=-1,ch=getchar();
    30     while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    31     return q*x;
    32 }
    33 
    34 il void insert(RG int from,RG int to){
    35     g[++num]=(edge){head[from],to},head[from]=num; return;
    36 }
    37 
    38 il void Push(RG int i){
    39     Q[++len]=i; RG int x=len;
    40     while (x>>1){
    41     if (k[Q[x>>1]]>=k[Q[x]]) break;
    42     swap(Q[x>>1],Q[x]),x>>=1;
    43     }
    44     return;
    45 }
    46 
    47 il void Pop(){
    48     Q[1]=Q[len--]; RG int x=1,v;
    49     while ((x<<1)<=len){
    50     v=x<<1; if ((v|1)<=len && k[Q[v|1]]>k[Q[v]]) v|=1;
    51     if (k[Q[x]]>=k[Q[v]]) break; swap(Q[x],Q[v]),x=v;
    52     }
    53     return;
    54 }
    55 
    56 il void solve(RG int s){
    57     len=0;
    58     for (RG int i=1;i<=n;++i){
    59     cnt[i]=d[i]; if (i==s) cnt[i]=n;
    60     if (!cnt[i]) Push(i);
    61     }
    62     for (RG int id=n;id;--id){
    63     if (!len){ b[s]=id; return; } RG int x=Q[1],v; Pop();
    64     if (!s) a[id]=x; else if (k[x]<id){ b[s]=id; return; }
    65     for (RG int i=head[x];i;i=g[i].nt){
    66         v=g[i].to; if (!(--cnt[v])) Push(v);
    67     }
    68     }
    69     return;
    70 }
    71 
    72 il void work(){
    73     n=gi(),m=gi(); for (RG int i=1;i<=n;++i) k[i]=gi();
    74     for (RG int i=1,u,v;i<=m;++i) u=gi(),v=gi(),insert(v,u),++d[u];
    75     for (RG int i=0;i<=n;++i) solve(i);
    76     for (RG int i=1;i<=n;++i) printf("%d ",a[i]); puts("");
    77     for (RG int i=1;i<=n;++i) printf("%d ",b[i]); return;
    78 }
    79 
    80 int main(){
    81     File("plane");
    82     work();
    83     return 0;
    84 }
  • 相关阅读:
    Unity 用代码设置UGUI的渲染层级
    C/C++常考基础面试题(更新)
    运行Jar包程序Shell
    Shell编程语法
    Spring多个数据源问题:DataSourceAutoConfiguration required a single bean, but * were found
    Maven项目的发布,发布到Nexus
    Consul入门
    application.properties 改成 application.yml
    奖学金申请模板
    jvm
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6986373.html
Copyright © 2011-2022 走看看