NOI2015 航空管制

来源:互联网 发布:股票套牢知乎 编辑:程序博客网 时间:2024/05/01 13:43

题目链接
再次吐槽bzoj不走心……

此题题面就已经提示正解了,和某序有关!!!

存边,并将每架飞机的起飞限制x改成n-x,就将第一问转化成一个求飞机最晚起飞时间的问题,用拓扑排序可解。
第二问:每次限制不起飞某架飞机p,而将其他能飞的飞机都飞出去(拓扑排序时不处理p结点,让p连出去的边都保留下来),此时飞机p必须起飞了,这个时间就是它在新问题中的最晚起飞时间,也就是原问题中的最早起飞时间。

似乎又是水题……

附代码

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,m,cnt,hd,tl;struct data{    int limit,num;}p[2010];struct dt{    int nex,to;}edge[20010];int lim[2010],getin[2010],gtin[2010],head[2010],q[2010];bool cmp(const data&aa,const data&bb){    return aa.limit<bb.limit;}void add(int start,int end){    edge[++cnt].nex=head[start];    edge[cnt].to=end;    head[start]=cnt;}void work(int x){    memcpy(gtin,getin,sizeof(getin));    hd=tl=0;//!!!    for(int t=1,i=1;i<=n;i++){        /*for(int t=1;t<=n;t++)            if(p[t].limit<i&&!gtin[p[t].num]&&x!=p[t].num) q[++tl]=p[t].num;*/        for(;t<=n&&p[t].limit<i;t++)            if(!gtin[p[t].num]&&p[t].num!=x) q[++tl]=p[t].num;          if(hd<tl){            int u=q[++hd];            for(int j=head[u];j;j=edge[j].nex){                gtin[edge[j].to]--;                if(!gtin[edge[j].to]&&x!=edge[j].to&&lim[edge[j].to]<i) q[++tl]=edge[j].to;            }        }        else return;    }       }int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        scanf("%d",&p[i].limit);        p[i].limit=n-p[i].limit;        p[i].num=i;        lim[i]=p[i].limit;    }    sort(p+1,p+n+1,cmp);    int a,b;    for(int i=1;i<=m;i++){        scanf("%d%d",&a,&b);        getin[a]++;        add(b,a);    }    work(0);    for(int i=tl;i>=2;i--) printf("%d ",q[i]);    printf("%d\n",q[1]);    for(int i=1;i<n;i++){        work(i);        printf("%d ",n-tl);    }    work(n);    printf("%d",n-tl);    return 0;}
原创粉丝点击