BZOJ2109: [Noi2010]Plane 航空管制 解题报告

来源:互联网 发布:红辣椒电影数据分析 编辑:程序博客网 时间:2024/05/15 01:10

写完发现我真是想多了,一直觉得nm+n2logn过不了,结果轻松过去了



这题好像没有原题的第一问呀,不过有没有第一问都差不多…


感觉上这题每个数最前的位置不能一起求的,所以考虑一个一个求
如果只求第k个数最前的位置是什么的话,因为题意要求有些航班只能在一些航班之后起飞,所以先建一个拓扑图,但如果是按照位置1~n这样弄,每次在入度为0的点里面不知道选哪个点,因为有后效性(直接选限制时间最小的点是错的)。
所以考虑反向建一个拓扑图,时间从n推到1,将第k个数隔离出来不考虑,每次只要在入度为0的点里随便取一个限制时间≥当前时间的就行了,如果找不到这样的点,因为题目保证有解,所以这个位置只能放第k个数。。。。取点可以用一个优先队列弄一下。。。。



code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<ctime>#include<cmath>#include<string>#include<vector>#include<string>#include<cstdio>#include<cstring>#include<climits>#include<cstdlib>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 2100;const int maxm = 110000;struct edge{    int y,nex;}a[maxm];int len,fir[maxn];int e[maxm][2];void ins(int x,int y){len++;a[len].y=y;a[len].nex=fir[x];fir[x]=len;}struct node{    int x,d;};bool operator <(node x,node y){return x.d<y.d;}priority_queue<node>q;int d[maxn],dt[maxn],ans[maxn],dk[maxn];int n,m;int main(){    memset(fir,0,sizeof fir); len=0;    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++) scanf("%d",&dk[i]);    for(int i=1;i<=m;i++)    {        scanf("%d%d",&e[i][0],&e[i][1]);        ins(e[i][1],e[i][0]);        d[e[i][0]]++;    }    for(int k=1;k<=n;k++)    {        for(int i=1;i<=n;i++)        {            dt[i]=d[i];            if(!dt[i]&&i!=k)             {                node tmp;                tmp.x=i;tmp.d=dk[i];                q.push(tmp);            }        }        int nw=n;        while(!q.empty())        {            node x=q.top();q.pop();            if(x.d<nw) break;            for(int l=fir[x.x];l;l=a[l].nex)            {                dt[a[l].y]--;                if(!dt[a[l].y]&&a[l].y!=k)                {                    node tmp;                    tmp.x=a[l].y;tmp.d=dk[a[l].y];                    q.push(tmp);                }            }            nw--;        }        ans[k]=nw;        while(!q.empty())q.pop();    }    for(int i=1;i<=n;i++)printf("%d ",ans[i]);    printf("\n");    return 0;}
0 0