NOI2010 航空管制 拓撲排序 貪心

2022-07-13 20:21:22 字數 1682 閱讀 7082

題目描述

世博期間,上海的航空客運量大大超過了平時,隨之而來的航空管制也頻頻發生。最近,小x就因為航空管制,連續兩次在機場被延誤超過了兩小時。對此,小x表示很不滿意。

在這次來煙台的路上,小x不幸又一次碰上了航空管制。於是小x開始思考關於航空管制的問題。

假設目前被延誤航班共有n個,編號為1至n。機場只有一條起飛跑道,所有的航班需按某個順序依次起飛(稱這個順序為起飛序列)。定義乙個航班的起飛序號為該航班在起飛序列中的位置,即是第幾個起飛的航班。

起飛序列還存在兩類限制條件:

• 第一類(最晚起飛時間限制):編號為i的航班起飛序號不得超過ki;

• 第二類(相對起飛順序限制):存在一些相對起飛順序限制(a, b),表示航班a的起飛時間必須早於航班b,即航班a的起飛序號必須小於航班b的起飛序號。

小x思考的第乙個問題是,若給定以上兩類限制條件,是否可以計算出乙個可行的起飛序列。第二個問題則是,在考慮兩類限制條件的情況下,如何求出每個航班在所有可行的起飛序列中的最小起飛序號。

題解

我好菜啊。。

對於第一問,我們可以倒著貪心,盡量把k大的往後放,搞乙個以k為關鍵字的大根堆,在反圖上拓撲一下就可以了,我在這想了半天,太菜了。。。

對於第二問,我們還是倒著放,和上邊一樣,這次我們不在堆中放i這個點,直到出現乙個不合法的點出現,這時我們再加入i點就可以了。

這樣的思路和這道題一樣。

**

#include#include

#include

#include

#define n 2002

#define m 10002

using

namespace

std;

intk[n],n,m,tot,head[n],du[n],num,pos[n],ans[n],d[n];

inline

intrd()

while(isdigit(c))

return f?-x:x;

}struct edgee[m];

inline

void add(int u,int v)

struct

node

};struct wfb[m];

priority_queue

q;int

main()

memcpy(du,d,

sizeof

(d));

for(int i=1;i<=n;++i)if(!du[i])q.push(node);

while(!q.empty()));}}

for(int i=n;i>=1;--i)printf("

%d ",pos[i]);puts(""

);

for(int o=1;o<=n;++o));

for(int g=n;g>=1;--g)

int u=q.top().id;q.pop();

if(k[u]break

;}

for(int i=head[u];i;i=e[i].n));}}

} for(int i=1;i<=n;++i)printf("

%d "

,ans[i]);

return0;

}

NOI2010 航空管制

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

NOI2010 航空管制

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

NOI2010 航空管制

貪心。對於第1個問,我們先建立拓撲圖,對於如果a必須在b前起飛,那麼連有向邊b a,並求出點的入度。將所有入度為0的點放在乙個優先佇列裡,按最大起飛編號從大到小排序。我們從後往前考慮起飛的航班。取出優先佇列中最大起飛編號最大的點,作為最後乙個航班,並刪去拓撲圖中與他相連的邊,如果有新的點的入度變成0...