题目描述
一条单向的铁路线上,依次有编号为 1,2,…,n1, 2, …, n 1,2,…,n的 nn n个火车站。每个火车站都有一个级别,最低为 111 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 xxx,则始发站、终点站之间所有级别大于等于火车站x xx 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)
例如,下表是5 5 5趟车次的运行情况。其中,前4 44 趟车次均满足要求,而第 555 趟车次由于停靠了 333 号火车站(222 级)却未停靠途经的 666 号火车站(亦为 222 级)而不满足要求。
现有 mmm 趟车次的运行情况(全部满足要求),试推算这n nn 个火车站至少分为几个不同的级别。
输入输出格式
输入格式:第一行包含 222 个正整数 n,mn, mn,m,用一个空格隔开。
第 i+1i + 1i+1 行(1≤i≤m)(1 ≤ i ≤ m)(1≤i≤m)中,首先是一个正整数 si(2≤si≤n)s_i(2 ≤ s_i ≤ n)si(2≤si≤n),表示第i ii 趟车次有 sis_isi 个停靠站;接下来有si s_isi个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。
输出格式:一个正整数,即 nnn 个火车站最少划分的级别数。
输入输出样例
说明
对于20% 20\%20%的数据,1≤n,m≤101 ≤ n, m ≤ 101≤n,m≤10;
对于 50%50\%50%的数据,1≤n,m≤1001 ≤ n, m ≤ 1001≤n,m≤100;
对于 100%100\%100%的数据,1≤n,m≤10001 ≤ n, m ≤ 10001≤n,m≤1000。
显然的拓扑排序,注意不要加重边。
#include <iostream> #include <cstdio> #include <queue> #include <vector> #include <cstring> #include <map> using namespace std; #define reg register inline int read() { int res = 0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48), ch=getchar(); return res; } int n, m; vector <int> son[1005]; int deg[1005]; int a[1005]; bool vis[1005]; int ans; struct date { int x, dep; }; bool mp[1005][1005]; int main() { n = read(), m = read(); for (reg int i = 1 ; i <= m ; i ++) { int s = read(); memset(vis, 0, sizeof vis); for (reg int j = 1 ; j <= s ; j ++) a[j] = read(), vis[a[j]] = 1; for (reg int j = 1 ; j <= s ; j ++) for (reg int k = a[1] ; k <= a[s] ; k ++) if (!vis[k] and !mp[a[j]][k]) deg[k]++, son[a[j]].push_back(k), mp[a[j]][k] = 1; } queue <date> q; for (reg int i = 1 ; i <= n ; i ++) if (!deg[i]) q.push((date){i, 1}); while(!q.empty()) { int x = q.front().x, d = q.front().dep;q.pop(); ans = max(ans, d); for (reg int i = 0 ; i < son[x].size() ; i ++) { deg[son[x][i]] --; if (!deg[son[x][i]]) q.push((date){son[x][i], d + 1}); } } cout << ans << endl; return 0; }