題目在洛谷\(P1983\)上html
題目:c++
一條單向的鐵路線上,依次有編號爲 \(1, 2, …, n1,2,…,n\)的 \(n\)個火車站。每一個火車站都有一個級別,最低爲 11 級。現有若干趟車次在這條線路上行駛,每一趟都知足以下要求:若是這趟車次停靠了火車站 \(x\),則始發站、終點站之間全部級別大於等於火車站\(x\) 的都必須停靠。(注意:起始站和終點站天然也算做事先已知須要停靠的站點)spa
例如,下表是\(5\)趟車次的運行狀況。其中,前\(4\)趟車次均知足要求,而第\(5\)趟車次因爲停靠了\(3\)號火車站(\(2\)級)卻未停靠途經的\(6\)號火車站(亦爲\(2\)級)而不知足要求。code
現有\(m\) 趟車次的運行狀況(所有知足要求),試推算這\(n\)個火車站至少分爲幾個不一樣的級別。htm
輸入輸出格式:blog
輸入:第一行包含\(2\)個正整數\(n, m\),用一個空格隔開。排序
第 \(i + 1\) 行\((1 ≤ i ≤ m)\)中,首先是一個正整數\(s_i(2 ≤ s_i ≤ n)\),表示第\(i\) 趟車次有\(s_i\) 個停靠站;接下來有\(s_i\)個正整數,表示全部停靠站的編號,從小到大排列。每兩個數之間用一個空格隔開。輸入保證全部的車次都知足要求。get
輸出:一個正整數,即\(n\)個火車站最少劃分的級別數。it
剛剛看到這道題時,我並無讀懂題,以爲是要用一個\(dp\)或者搜索什麼的(也有多是我搜索題作多了class
看到題目,咱們知道,假設一個車次從\(x\)車站駛向\(y\)車站,\(c_i\)表示第\(i\)個車站的車站等級。那麼中間的\(c_i(x \leq i \leq y)\)必定知足\(c_i\leq c_x\)和\(c_i \leq c_y\)。這樣的話,咱們就能夠構造出一個有向圖,級別低的車站指向級別高的車站。這樣一來,題目就轉化成了拓撲排序的簡單題了
根據上面的題目分析,咱們能夠得出如下解題方法:
首先將有向圖建好,建圖的方法是:對於每個車次,其中停靠的車站咱們不能肯定與始發站和終點站的關係,那麼咱們就假設這些車站的等級是相同的,而中間沒有停靠的車站則向停靠過的車站(包括始發站和終點站)連一條邊。
進行了這項操做以後,咱們發現這\(n\)個車站各自有不一樣的入度,按照入度進行排序,若是有不一樣的入度,\(ans++\)最後的\(ans\)就是咱們要求的答案。
#include<bits/stdc++.h> using namespace std; const int MAXN=3000010; const int maxn=1005; int head[MAXN],to[MAXN],nxt[MAXN]; int in[maxn],cnt,dep[maxn]; int a[maxn],flag[maxn],vis[maxn][maxn],ans; //flag標記是否停靠,vis去重邊 inline void add(int u,int v) { cnt++; to[cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; }//鄰接鏈表存邊 int n,m; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { memset(a,0,sizeof(a)); memset(flag,0,sizeof(flag)); int k; scanf("%d",&k); for(int j=1;j<=k;j++) { scanf("%d",&a[j]); flag[a[j]]=1;//標記 } for(int j=a[1]+1;j<=a[k];j++) { if(!flag[j]) { for(int p=1;p<=k;p++) { if(!vis[j][a[p]]) { in[a[p]]++; add(j,a[p]); vis[j][a[p]]=1; } } } } } queue<int> q; for(int i=1;i<=n;i++) { if(!in[i]) q.push(i),dep[i]=1; //剛開始入度就爲0的點深度爲1 } while(!q.empty()) { int top=q.front(); q.pop(); for(int e=head[top];e;e=nxt[e]) { int v=to[e]; dep[v]=max(dep[v],dep[top]+1); //這個不加max也能夠,由於下面的ans已經取過max了 //不過加上也沒問題 ans=max(ans,dep[v]);//更新答案 in[to[e]]--;//入度-- if(!in[to[e]]) q.push(to[e]); } } cout<<ans; }
這是\(ych\)大神的代碼(本蒟蒻表示還不會寫)