You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
/**
|
|
|
|
|
思路:非停靠-->停靠站连边,然后用拓扑排序求深度。
|
|
|
|
|
*/
|
|
|
|
|
const int N = 1010; //题目中要求结点数是1000个上限
|
|
|
|
|
int n, m; //n个车站,m个车次
|
|
|
|
|
vector<int> edge[N]; //邻接表
|
|
|
|
|
int in[N]; //入度数组
|
|
|
|
|
bool flag[N]; //flag[i]标识是不是停靠站点
|
|
|
|
|
bool st[N][N]; //用来判断是不是已经存在了i到j的边
|
|
|
|
|
int ans; //答案
|
|
|
|
|
int a[N]; //停靠站信息
|
|
|
|
|
|
|
|
|
|
//结构体,携带两个信息,一个是哪个车站,另一个是几级
|
|
|
|
|
struct Node {
|
|
|
|
|
int sq_sum;
|
|
|
|
|
int step;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//拓扑排序,计算出层次
|
|
|
|
|
void topSort() {
|
|
|
|
|
//拓扑排序
|
|
|
|
|
queue<Node> q; //拓扑用队列
|
|
|
|
|
//查找所有入度为0的结点入队列,第一个参数是结点号,第二个参数是步数
|
|
|
|
|
for (int i = 1; i <= n; ++i) if (!in[i]) q.push({i, 1});
|
|
|
|
|
//开始拓扑套路
|
|
|
|
|
while (!q.empty()) {
|
|
|
|
|
//结点ID
|
|
|
|
|
int u = q.front().num;
|
|
|
|
|
//步数
|
|
|
|
|
int step = q.front().step;
|
|
|
|
|
q.pop();
|
|
|
|
|
//注意修改ans的值,保持最大值
|
|
|
|
|
ans = max(ans, step);
|
|
|
|
|
for (auto v:edge[u]) {
|
|
|
|
|
in[v]--;
|
|
|
|
|
if (!in[v]) q.push({v, step + 1});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
cin >> n >> m;
|
|
|
|
|
while (m--) {
|
|
|
|
|
//每次重新初始化状态数组
|
|
|
|
|
memset(flag, 0, sizeof(flag));
|
|
|
|
|
int s; //本轮的停靠站数量
|
|
|
|
|
cin >> s;
|
|
|
|
|
//读入停靠站信息
|
|
|
|
|
for (int i = 1; i <= s; ++i) cin >> a[i], flag[a[i]] = true; //标识是停靠站
|
|
|
|
|
|
|
|
|
|
//遍历出发站到终点站,这里可不是全部车站啊!只有在范围内的才能明确等级关系啊!!!注意
|
|
|
|
|
//这里a[1]是指起点,a[s]是指终点,就是这个车次的出发点到结束点,这中间有停靠的,有不停靠的,
|
|
|
|
|
// 不停靠的站等级一定是小于停靠的
|
|
|
|
|
for (int i = a[1]; i <= a[s]; ++i)
|
|
|
|
|
//如果不是停靠站,那就是等级低的站,需要连边~,非停靠站-->停靠站 连边
|
|
|
|
|
if (!flag[i]) {
|
|
|
|
|
int source = i; //出发结点,在这里是指非停靠站点
|
|
|
|
|
for (int j = 1; j <= s; ++j) {
|
|
|
|
|
int target = a[j]; //a[j]代表所有依靠站
|
|
|
|
|
if (!st[source][target]) {//没配置过边的有效,重边只留一条.因为不同的车次,
|
|
|
|
|
// 存在两条一样的边是很正常的,但没有必要保留多个。
|
|
|
|
|
edge[source].push_back(target);
|
|
|
|
|
st[source][target] = true;//标识已配置
|
|
|
|
|
in[target]++;//入度++
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//拓扑排序
|
|
|
|
|
topSort();
|
|
|
|
|
//输出结果
|
|
|
|
|
cout << ans << endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|