车站分级

https://www.luogu.com.cn/problem/P1983
#include <bits/stdc++.h>
using namespace std;
int n, m;
int li[1001];
bool to[1001][1001];
bool en[1001];
int input_cnt[1001];
int deep[1001];
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; i++) {
        int t;
        scanf("%d", &t);
        for (int j = 1; j <= t; j++)//将经过的车站读入
            scanf("%d", &li[j]);
        for (int j = li[1]; j <= li[t]; j++)//将始发站到终点站的标记清空
            en[j] = 0;
        for (int j = 1; j <= t; j++)//经过的车站标记为1
            en[li[j]] = 1;
        for (int j = li[1]; j <= li[t]; j++) {//经过的车站的级别比未经过的级别大,将经过的车站连向未经过的车站
            if (en[j] == 1)//如果该站经过则跳过
                continue;
            else {//找到了未经过的车站
                for (int k = 1; k <= t; k++) {//将所有经过过的车站与该未经过的车站相连 
                    if (!to[li[k]][j]) {//如果边没有被添加过则添加
                        to[li[k]][j] = 1;//添加边
                        input_cnt[j]++;//入读+1
                    }
                }
            }
        }
    }
    queue<int> que;
    for (int i = 1; i <= n; i++) {
        if (input_cnt[i] == 0) {
            deep[i] = 1;//初始深度为1
            que.push(i);
        }
    }
    int ans = 0;
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        for (int v = 1; v <= n; v++) {
            if(!to[u][v])//不存在边,跳过
                continue;
            input_cnt[v]--;//存在边,让目标入度-1
            deep[v] = max(deep[v], deep[u] + 1);//更新目标的最大深度
            ans = max(ans, deep[v]);//以全体的最大深度作为答案
            if (input_cnt[v] == 0)
                que.push(v);
        }
    }
    printf("%d", ans);
}

点赞

发表回复