#include using namespace std; /** 思路:非停靠-->停靠站连边,然后用拓扑排序求深度。 */ const int N = 1010; //题目中要求结点数是1000个上限 int n, m; //n个车站,m个车次 vector 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 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; }