洛谷 P1983 車站分級 拓撲排序

2022-02-13 14:24:57 字數 2573 閱讀 5911

一條單向的鐵路線上,依次有編號為 1,2,…,n的 n個火車站。每個火車站都有乙個級別,最低為1 級。現有若干趟車次在這條線路上行駛,每一趟都滿足如下要求:如果這趟車次停靠了火車站 x,則始發站、終點站之間所有級別大於等於火車站x 的都必須停靠。(注意:起始站和終點站自然也算作事先已知需要停靠的站點)

例如,下表是5 趟車次的運**況。其中,前4 趟車次均滿足要求,而第 5趟車次由於停靠了 3號火車站(2級)卻未停靠途經的 6號火車站(亦為 2 級)而不滿足要求。

現有 m趟車次的運**況(全部滿足要求),試推算這n個火車站至少分為幾個不同的級別。

輸入格式:

第一行包含 2個正整數 n,m用乙個空格隔開。

第 i+1行(1≤i≤m)中,首先是乙個正整數 si(2≤si≤n),表示第i 趟車次有 si個停靠站;接下來有si​個正整數,表示所有停靠站的編號,從小到大排列。每兩個數之間用乙個空格隔開。輸入保證所有的車次都滿足要求。

輸出格式:

乙個正整數,即 n個火車站最少劃分的級別數。

輸入樣例#1:

9 2 

4 1 3 5 6

3 3 5 6

輸出樣例#1:

2
輸入樣例#2:

9 3 

4 1 3 5 6

3 3 5 6

3 1 5 9

輸出樣例#2:

3
對於20% 的資料,1≤n,m≤10;

對於 50%的資料,1≤n,m≤100;

對於 100%的資料,1≤n,m≤1000。

首先第一眼看到這個題,就知道這是這是拓撲排序(當時在講拓撲排序),但是此題最難的地方在於建邊:對於給定的兩個車站(起點站和終點站),必須先停在這兩個車站之間所有>=這兩個車站的車站,但是還有乙個等於,所以我們需要換一種思路。

既然停下的是所有大於等於起點站和終點站級別的車站,那麼也就是說,沒停下的車站的級別一定是小於起點站和終點站的,又因為起點站和終點站的級別小於等於中間停下的車站,所以最終的出結論,沒停下的車站一定是小於停下的所有的車站的級別(包括起點站和終點站),換句話說,停下的所有車站的級別一定》未停下的的車站的級別。

我們看到了》,就表明可以用拓撲排序來完成了。

本題還有乙個難點就是需要優化,設想當多趟列車經過了相同的站點時,很可能會炸空間——記錄入度的陣列。所以我們需要在每一次建邊前,先判斷一下這兩個車站是否已經有了邊了,如果有了邊了,那麼記錄入讀的陣列也不需要再加一了。

最後進行一遍有點變動的拓撲排序:用入度為0的點去更新與它相鄰的點的級別。(我總感覺像求最短路)。

總結一下,這個題最難的地方就是建圖和優化。

最後,附上ac**(帶有解析)。

1 #include2 #include3 #include4

using

namespace

std;

5int n,m,k,in[1005]; //

k是每一趟車停下的車站數。in[i]存的是點的入度(拓撲排序用)。

6int gragh[1005][1005],tou,wei; //

gragh存圖,這裡是鄰接矩陣存圖。tou是每一趟列車的始發站,wei是終點站。

7int stop[1005],vis[1005]; //

stop存的是每一趟車停下的車站,vis[j]存的是車站j有沒有停下。

8int ans,level[1005]; //

level[i]存的是第i個車站的等級。ans存的是level中的最大值。

9 queue q; //

拓撲排序用,保證佇列裡的點都是入度為0的點

10int

main()

1124

//建圖的核心部分

25for(int a=1;a<=k;a++) //

列舉停下的每乙個車站

26for(int b=tou;b<=wei;b++)32}

33 } //

建圖完畢。

34//

開始拓撲排序:

35for(int i=1;i<=n;i++)40}

41while(!q.empty())50}

51 ans=max(ans,level[front]); //

隨時去max,保證最後求出的ans一直是到目前為止的最大等級。 52}

53 cout<

54return0;

55 }

ac**(附有詳細解析)

洛谷 P1983 車站分級(拓撲排序)

一條單向的鐵路線上,依次有編號為 1,2,n的 n個火車站。每個火車站都有乙個級別,最低為 1 級。現有若干趟車次在這條線路上行駛,每一趟都滿足如下要求 如果這趟車次停靠了火車站 x,則始發站 終點站之間所有級別大於等於火車站x 的都必須停靠。注意 起始站和終點站自然也算作事先已知需要停靠的站點 例...

洛谷 P1983 車站分級(拓撲排序)

思路 對於每一趟車,將其經過的車站中,停靠的和不停靠的連一條邊,注意邊的去重,要雙向標記,不然有個點會超時,這樣拓撲排序遞推一下就能分級出來 include using namespace std struct node const int n 1005 int n,m int ru n vecto...

洛谷P1983 車站分級 拓撲排序

一條單向的鐵路線上,依次有編號為 1,2,n的 n 個火車站。每個火車站都有乙個級別,最低為 1 級。現有若干趟車次在這條線路上行駛,每一趟都滿足如下要求 如果這趟車次停靠了火車站 x,則始發站 終點站之間所有級別大於等於火車站 x 的都必須停靠。注意 起始站和終點站自然也算作事先已知需要停靠的站點...