• [luogu p1983] 车站分级


    传送门

    车站分级

    题目描述

    一条单向的铁路线上,依次有编号为 (1, 2, ..., n)(n)个火车站。每个火车站都有一个级别,最低为 (1) 级。现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 (x),则始发站、终点站之间所有级别大于等于火车站(x) 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)

    例如,下表是(5)趟车次的运行情况。其中,前(4) 趟车次均满足要求,而第 (5) 趟车次由于停靠了 (3) 号火车站((2) 级)却未停靠途经的 (6) 号火车站(亦为 (2) 级)而不满足要求。

    现有 (m) 趟车次的运行情况(全部满足要求),试推算这$ n$ 个火车站至少分为几个不同的级别。

    输入输出格式

    输入格式

    第一行包含 (2) 个正整数 (n, m),用一个空格隔开。

    (i + 1)((1 ≤ i ≤ m))中,首先是一个正整数 (s_i(2 ≤ s_i ≤ n)),表示第$ i$ 趟车次有 (s_i) 个停靠站;接下来有$ s_i$个正整数,表示所有停靠站的编号,从小到大排列。每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。

    输出格式

    一个正整数,即 (n) 个火车站最少划分的级别数。

    输入输出样例

    输入样例 #1

    9 2
    4 1 3 5 6
    3 3 5 6
    

    输出样例 #1

    2
    

    输入样例 #2

    9 3
    4 1 3 5 6
    3 3 5 6
    3 1 5 9
    

    输出样例 #2

    3
    

    说明

    对于(20\%)的数据,(1 ≤ n, m ≤ 10)

    对于 (50\%)的数据,(1 ≤ n, m ≤ 100)

    对于 (100\%)的数据,(1 ≤ n, m ≤ 1000)

    分析

    此题我们要抓住原题中的一句话:

    如果这趟车次停靠了火车站 (x),则始发站、终点站之间所有级别大于等于火车站(x) 的都必须停靠。

    反过来也就是说:

    在一个车次中,停下来的车站一定比没停下来的车站的级别高。

    现在让你求最少分为多少级,也就是说,我们用 (1, 2, 3, 4) 给级别编号,程序让我们求的就是最高的那个级别。

    既然在一个车次中停下来的车站一定比没停下来的车站的级别高,我们就可以根据这个让级别低的向级别高的连边,最终就会形成一个DAG。对于这个DAG进行topsort,并同时进行递推,便可以得出每一个车站的等级了,最后取等级最大值即可。

    上代码。

    代码

    /*
     * @Author: crab-in-the-northeast 
     * @Date: 2020-10-01 09:14:56 
     * @Last Modified by: crab-in-the-northeast
     * @Last Modified time: 2020-10-01 11:32:31
     */
    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    
    const int maxn = 1005;
    const int maxm = 1005;
    
    std :: vector <int> G[maxn];
    int ind[maxn];
    bool vis[maxn][maxn];
    
    int n, m;
    int topsort() {
        std :: queue <std :: pair <int, int> > q;
        int ans = 1;
        for (int i = 1; i <= n; ++i)
            if (ind[i] == 0)
                q.push(std :: make_pair(i, 1));
    
        while (!q.empty()) {
            int u = q.front().first, level = q.front().second;
            q.pop();
            for (int i = 0; i < G[u].size(); ++i) {
                int v = G[u][i];
                --ind[v];
                if (ind[v] == 0) {
                    q.push(std :: make_pair(v, level + 1));
                    ans = ans > level + 1 ? ans : level + 1;
                }
            }
        }
    
        return ans;
    }
    
    int main() {
        std :: scanf("%d %d", &n, &m);
    
        for (int i = 1; i <= m; ++i) {
            int s;
            std :: scanf("%d", &s);
            int stop[maxn];
            bool is_stop[maxn] = {false};
            for (int j = 1; j <= s; ++j) {
                std :: scanf("%d", &stop[j]);
                is_stop[stop[j]] = true;
            }
    
            for (int j = stop[1]; j <= stop[s]; ++j) {
                if (!is_stop[j]) {
                    for (int k = 1; k <= s; ++k) {
                        if (!vis[j][stop[k]]) {
                            ++ind[stop[k]];
                            G[j].push_back(stop[k]);
                            vis[j][stop[k]] = true;
                        }
                    }
                }
            }
        }
    
        std :: printf("%d
    ", topsort());
        return 0;
    }
    

    评测记录

    评测记录

  • 相关阅读:
    API网络数据安全
    【值得收藏】一文掌握用户画像系统构建全流程
    手把手教你从0到1学会tensorflow进行模型训练,并能在网页轻松运行
    APP选择第三方消息推送平台时,有哪些需要关注的重要性能指标?
    如何防薅羊毛?个推基于大数据风控引擎助力APP反欺诈!
    微信为什么要搞一个小游戏?
    关于 JS 模块化的最佳实践总结
    张小龙2019微信公开课15个看点总结
    编程:从前有一个傻呆程序员,老婆交给他一项任务,他办了四次才满意
    JS是如何计算 1+1=2 的?
  • 原文地址:https://www.cnblogs.com/crab-in-the-northeast/p/luogu-p1983.html
Copyright © 2020-2023  润新知