1. 程式人生 > >[NOIP2013]車站分級

[NOIP2013]車站分級

algorithm namespace 站點 ios span ron ons col getc

原題傳送門

這道題根據題意,能得出該結論:

·一條線路經過的站點,停靠站點等級一定大於未停靠的站點

又因為輸入保證所有的車次都滿足要求,所以滿足偏序集關系。我們可以將站點的大小關系用$DAG$圖表示,即將一條線路中停靠站點向未停靠站點連有向邊。最後求一遍DAG圖中最長鏈。

問題在於構圖的復雜度為$O(n^2m)$,無法接受。

這裏采用構建虛點的方式解決構圖問題,如下圖

技術分享圖片

此時復雜度為$O(nm)$。

最後註意最長鏈包括了虛點,把它去掉即可。

 1 #include <iostream>
 2 #include <cstdio>
 3
#include <cstring> 4 #include <algorithm> 5 #include <queue> 6 7 using namespace std; 8 9 #define re register 10 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 11 #define repd(i, a, b) for (re int i = a; i >= b; --i) 12 #define maxx(a, b) a = max(a, b); 13
#define minn(a, b) a = min(a, b); 14 #define LL long long 15 #define inf (1 << 30) 16 17 inline int read() { 18 int w = 0, f = 1; char c = getchar(); 19 while (!isdigit(c)) f = c == - ? -1 : f, c = getchar(); 20 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^
0), c = getchar(); 21 return w * f; 22 } 23 24 queue<int> q, q0, empty; 25 26 const int maxn = 1e3 + 5; 27 28 int a[maxn][maxn], e[maxn << 1][maxn << 1], n, m, r[maxn], d[maxn << 1], ans; 29 30 int main() { 31 n = read(), m = read(); 32 33 rep(i, 1, m) { 34 a[i][0] = read(); 35 memset(r, 0, sizeof(r)); 36 rep(j, 1, a[i][0]) a[i][j] = read(), r[a[i][j]] = 1; 37 rep(j, a[i][1], a[i][a[i][0]]) if (r[j]) e[j][n+i] = 1; else e[n+i][j] = 1; 38 } 39 40 rep(i, 1, n+m) { 41 rep(j, 1, n+m) 42 d[i] += e[j][i] ? 1 : 0; 43 if (!d[i]) q.push(i); 44 } 45 46 while (!q.empty()) { 47 while (!q.empty()) { 48 int u = q.front(); q.pop(); 49 rep(i, 1, n+m) if (e[u][i]) { 50 d[i]--; 51 if (!d[i]) q0.push(i); 52 } 53 } 54 q = q0; q0 = empty; 55 ans++; 56 } 57 58 printf("%d", (ans + 1) >> 1); 59 60 return 0; 61 }

[NOIP2013]車站分級