洛谷P1983 车站分级 ( 拓扑 or 差分约束) 题解

题目来源:

https://www.luogu.org/problemnew/show/P1983

题目描述:

题目描述

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

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

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

输入输出格式

输入格式:

第一行包含 22 个正整数 n, mn,m,用一个空格隔开。

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

输出格式:

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

输入输出样例

输入样例#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\%20%的数据,1 ≤ n, m ≤ 101≤n,m≤10;

对于 50\%50%的数据,1 ≤ n, m ≤ 1001≤n,m≤100;

对于 100\%100%的数据,1 ≤ n, m ≤ 10001≤n,m≤1000。

解题思路:

     我一开始也是想的差分约束,后来据说卡差分约束,就改成了拓扑了,我们可以知道一辆车没经过的站,一定比经过的站级别低,我们通过这个建边,然后bfs一下,求出最大值即可。。

代码:

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
int rd[1005],dj[1005];
bool jl[1005],pd[1005][1005];
vector<int>E[1005];
inline int getint()
{
    char ch;
    int res=0;
    while(ch=getchar(),ch<'0'||ch>'9');
    res=ch-48;
    while(ch=getchar(),ch>='0'&&ch<='9')
    res=(res<<3)+(res<<1)+ch-48;
    return res;
}
int main()
{
    memset(rd,0,sizeof(rd));
    memset(pd,0,sizeof(pd));
    int n,m,maxn=0;
    n=getint();m=getint();
    for(int i=1;i<=m;i++)
    {
        vector<int>EE;
        int a,b,bi,ed;
        memset(jl,0,sizeof(jl));
        a=getint();
        int fr,se;
        for(int j=1;j<=a;j++)
        {
            b=getint();
            se=b;
            if(j==1)bi=b;
            if(j==a)ed=b;
            if(j==1){
                fr=b,se=b;
            }
            for(int t=fr+1;t<se;t++)
            EE.push_back(t);
            jl[b]=1;
            fr=se;
        }
        for(int j=bi;j<=ed;j++)
        if(jl[j]){
            for(int t=0;t<EE.size();t++)
            {
                int v=EE[t];
                if(!pd[v][j]){
                    E[v].push_back(j);
                    rd[j]++;
                    pd[v][j]=1;
                }
                
            }
        }
    }
    queue<int>q;
    for(int i=1;i<=n;i++)
    {
        if(!rd[i]){
            q.push(i);
        }
    }
    while(!q.empty()){
        int now=q.front();
        q.pop();
        for(int i=0;i<E[now].size();i++)
        {
            int v=E[now][i];
            rd[v]--;
            if(!rd[v]){
                dj[v]=dj[now]+1;
                if(dj[v]>maxn)maxn=dj[v];
                q.push(v);
            }
        }
    }
    cout<<maxn+1<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40400202/article/details/82714511