bzoj2109 航空管制

2021-08-10 05:16:44 字數 1988 閱讀 1612

這題不難想到二分答案。。

你先對大小關係建乙個反圖,表示如果你想知道這個點,你必須先得到那個點的狀態

由於保證有解,所以這是乙個拓撲圖

然後你就拓撲排序地走。。

每乙個點就是連向它所有點的最小值,以及自己的時間,取乙個最小值值i,表示1~i它都可以選

策略,肯定是只要可以,就往後面放,正確性顯然

於是我們就要找在i前面的空位

這個顯然可以用乙個並查集來維護

對於當前點,你還要對你二分的答案取最小值

然後不合法情況就是存在乙個點沒有可以放的位置

然後就可以了

於是這個做法,時間複雜度是o(

nmlo

gn)

因為你每一次都要拓撲走一次。。

不知道有沒有常數好的人能過,反正我t了,對拍發現大概是正解的兩倍

然後我們繼續考慮優化,我們發現,對於同乙個點,無論二分答案是什麼,有許多東西的狀態都是固定的,就是拓撲序與他無關的

然後我們對於每乙個點,可以先跑半個圖,表示這些無論二分值為什麼都是不會變的,然後到時候就直接從一半開始跑,這樣就省時多了

時間複雜度o(

跑得過)

#include

#include

#include

#include

#include

#include

using namespace std;

const int max=1

<<30;

const int n=2005;

const int m=10005;

int n,m;

ints[n];

struct qq

e[m];int num,last[n];

int d[n];

void init (int

x,int

y)int d[n];

int lalal[n];//這個點在那個位置

int f[n];

int find (int

x)int

q[n];

inline int

read()

while(ch>='0'&&ch<='9')

return

x*f;

}int lalal[n];//一些預處理的

int dd[n];//也是一些預處理的

int f[n];

int st,ed;

int s,t;

bool check (int x,int shen)//排在這一位行不行

}// printf("tyb:%d

%d\n",st,ed);

while (st<=ed)

}st++;

}//printf("yes\n");

return true;

}void prepare (int now)

}while (st<=ed)

for (int i=last[x];i!=-1;i=e[i].last)}}

st++;

}/* printf("\nyes:");

for (int u=1;u<=n;u++) printf("%d ",lalal[u]);

printf("\n");*/

for (int i=1;i<=n;i++) lalal[i]=lalal[i];

for (int i=1;i<=n;i++) dd[i]=d[i];

for (int i=1;i<=n;i++) f[i]=f[i];

s=st;t=ed;

}int main()

for (int u=1;u<=n;u++) dd[u]=d[u]=d[u];

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

else l=mid+1;

}printf("%d ",ans);

}return

0;}

BZOJ 2535 Plane 航空管制2

題意 n個飛機一次出航。第i個飛機在出航序列中的序號不大於ki。另外有一些限制,表示飛機a的出航序號小於飛機b。1 輸出乙個合法的出航序列 2 輸出每個飛機最早的出航序號。思路 參考這裡。第一問比較好搞定。對於給出的,我們不妨建立有向邊。那麼b的所有孩子的出航序號必然小於b的出航序號。按照這個拓撲排...

NOI2010 航空管制

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

NOI2010 航空管制

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