NOI2010 航空管制

2022-05-15 06:09:57 字數 2772 閱讀 8841

貪心。對於第1個問,我們先建立拓撲圖,對於如果a必須在b前起飛,那麼連有向邊b->a,並求出點的入度。

將所有入度為0的點放在乙個優先佇列裡,按最大起飛編號從大到小排序。

我們從後往前考慮起飛的航班。

取出優先佇列中最大起飛編號最大的點,作為最後乙個航班,並刪去拓撲圖中與他相連的邊,如果有新的點的入度變成0,繼續加入優先佇列裡。

重複操作次即可。

如果問第i個航班最早可以什麼時候起飛,我們可以在優先佇列中,如果發現最大起飛編號最大的點是第i號航班,我們看看最大起飛編號第二大的點能不能先放,如果能就放最大起飛編號第二大的點;否則這個位置就是第i個航班最早可以起飛的位置了。

時間複雜度o(nm+n^2logn)。

#include#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#include適用於cf,uoj,但不適用於poj

using

namespace

std;

typedef

long

long

ll;typedef

double

db;typedef pair

pii;

typedef complex

cp;

#define mmst(a,v) memset(a,v,sizeof(a))

#define mmcy(a,b) memcpy(a,b,sizeof(a))

#define fill(a,l,r,v) fill(a+l,a+r+1,v)

#define re(i,a,b) for(i=(a);i<=(b);i++)

#define red(i,a,b) for(i=(a);i>=(b);i--)

#define ire(i,x) for(typedef(x.begin()) i=x.begin();i!=x.end();i++)

#define fi first

#define se second

#define m_p(a,b) make_pair(a,b)

#define sf scanf

#define pf printf

#define two(k) (1<

inline t sqr(t x)

template

inline void upmin(t &t,t tmp)

template

inline void upmax(t &t,t tmp)

const db eps=1e-9

;inline

int sgn(db x)

const db pi=acos(-1.0);

inline

intgint()

for(;z!=eof && isdigit(z);res=res*10+z-'

0',z=getchar());

return (neg)?-res:res;

}inline ll gll()

for(;z!=eof && isdigit(z);res=res*10+z-'

0',z=getchar());

return (neg)?-res:res;

}const

int maxn=2000

;const

int maxm=10000;

intn,m;

int last[maxn+10];

int du[maxn+10

];int now,first[maxn+10

];struct tedgeedge[maxm+100

];int used[maxn+10

];int

out[maxn+10];

inline

void addedge(int u,int v)

struct cmp};

priority_queue

,cmp>q;

intmain()

re(i,

1,n)du[i]=used[i]=0

; re(i,

0,now)du[edge[i].v]++;

re(i,

1,n)if(du[i]==0

)q.push(pii(i,last[i]));

red(j,n,1)

}re(i,

1,n)pf("

%d ",used[i]);pf("\n"

);

intt;

re(t,

1,n)

else

}else

used[j]=id;

for(i=first[used[j]],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)}}

re(i,

1,n)pf("

%d ",out[i]);pf("\n"

);

return0;

}

view code

NOI2010 航空管制

二元組的限制 考慮拓撲排序 正向拓撲不能保證最優,因卡的是結束時間 所以方向建圖topo 從n為0時間,相當於在n k i 的時間出現一架飛機 小根堆維護,每次選擇當前最早出現的一架飛機起飛。由於保證有解,這個顯然是正確的,對於當前只有一架飛機,不飛白不飛 當然也不能不飛 多架飛機,先飛後飛反正都是...

NOI2010 航空管制

首先第一問是很好做的,因為題目中保證有合法解,所以我們盡量讓期限晚的航班晚起飛.所以就是反著建圖,按照拓撲序給每個航班安排時間.第二問要求問所有合法解中每個航班最早什麼時候能起飛.那麼還是參考第一問的思路,額外的一點就是讓能安排在它後面的航班都安排到後面.所以就是先限制不選它,直到剩下的沒有辦法再選...

NOI2010 航空管制

對於第一問,對於每條限制 u,v 我們連邊 v rightarrow u 這樣將構成一張 rm dag 首先先拓撲排序,對於拓撲序考前的點我們先讓他盡量往後放,顯然這樣是最優的,因為我們在偏序滿足條件的情況下讓每個點盡量後放以保證方案的合法性,但需要注意的一點是可能拓撲序大的點能放的位置比較靠後而拓...