【問題描述】
在乙個byteland上有一副非常有名的圖畫需要被封存。這個作品需要在2個實驗室進行處理。這個處理過程被分為許多步驟。對於每個步驟,我們知道它必須要在哪個實驗室進行。
在兩個實驗室之間運輸這些這些美麗但又易碎的畫會帶來額外的風險,因此這個運輸的過程需要盡可能的被避免。理想情況下所有的工作都會在第乙個實驗室做完,然後剩下的在另乙個實驗室完成,但是有些步驟必須在另一步驟完成之後才能完成。你的任務是找到乙個工作的順序,讓這個被運輸的過程最少。輸出需要運輸的次數。
【輸入格式】
第一行n和m,代表著n個步驟,和m個先後關係。下面一行n個數字,第i個數字是1或2,代表了第i個工作需要在哪個實驗室完成,下面m行i,j,代表了第i個工作必須在第j個工作前完成。
你可以認為這個題目必有解
【輸出格式】
輸出最少需要的運輸次數。
【輸入樣例】
5 6
1 2 1 2 1
1 2
1 3
2 4
3 4
2 5
3 5【輸出樣例】
【資料範圍與約定】
30%資料保證n<=5。
100%資料中n<=100000,m<=1000000。
對於第1或第2個實驗室,我們分別建兩個佇列儲存當前進行能夠在第1或第2個實驗室完成的工作。然後進行拓撲排序:
[1]、每次選取入度為0的點加入兩個佇列;
[2]、要使運輸次數最少,就肯定要盡量在同乙個佇列裡選取能完成的步驟,因此記乙個狀態st
,表示當前我們所選取的是第st
個佇列;
[3]、每次從第st
個佇列中取出隊頭元素作為進行的步驟,那麼在該步驟之後完成的步驟入度都要減少1;
[4]、如果乙個隊列為空,表示現在我們已經不能一直在同乙個實驗室裡完成一些步驟,因此要換乙個佇列來取出隊頭元素,同時運輸次數加一,直到兩個佇列都為空為止。
另外因為st
的最初值可能為
1 或
2(最初可能在任意乙個實驗室裡),所以對於這兩種情況,我們都要計算一遍,最後對兩者取乙個最小值。
【**】
#include
#include
using
namespace
std;
const
int n = 1e5 + 5, m = 1e6 + 5;
int rin[n], cur[n], a[n], n, m;
int lst[n], nxt[m], to[m], t;
inline
int get()
inline
int min(const
int &x, const
int &y)
inline
void addedge(const
int &x, const
int &y)
inline
int query(int st)
return ans;
}int main()
printf("%d\n", min(query(0), query(1)));
fclose(stdin); fclose(stdout);
return
0;}
日常訓練 壓縮
巨大的文字往往令人頭疼,特別是文字內容有大量重複的情況下,巨大的文字不便於運輸和閱讀,於是我們提出了noip nonsense obivous index pattern 荒謬的顯然索引法 一種 有效的 壓縮文字的方法。noip壓縮後的格式很特別,乙個文字壓縮後由若干個單元組成,每個單元由3部分組成...
日常訓練 Tree
j 對於h u j 時間複雜度的證明也是比較經典了,每次列舉的是sz eu s zev 相當於每次從a,b 中各任選一點,它們的lc a 為 u 這樣的點對列舉不會重複,因此總的時間複雜度為o n2 include include include include include using name...
日常訓練 mod
給定 p 1,p 2,p n,b 1,b 2,b m 求滿足 x mod p 1 equiv a 1,x mod p 2 equiv a 2,x mod p n equiv a n 的 x 對 b 1,b 2,b m 取模的結果.第一行兩個整數 n,m 接下來 n 行,每行有乙個整數 a i 接下來...