P1983 车站分级

摘要:
这条线路上有几列列车运行,每列列车都满足以下要求:如果这列列车停在火车站xx,那么在始发站和终点站之间所有等级大于或等于火车站xx的列车都必须停车。其中,前44列符合要求,而第55列不符合要求,因为它停在33号火车站(22级),但不停在66号火车站。根据现有mm车次的运行情况,计算得出nn火车站至少可以分为几个不同的等级。

题目描述

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

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

P1983 车站分级第1张

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

输入输出格式

输入格式:

 

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

第 i + 1i+1 行 (1 ≤ i ≤ m)(1im) 中,首先是一个正整数 s_i(2 ≤ s_i ≤ n)si(2sin) ,表示第 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 ≤ 101n,m10 ;

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

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

Solution:

  本题经典的拓扑序DP,关键是建图卡时,需要线段树优化建图。

  首先由每次的停车情况可以确定出那些没有停车的点的等级一定小于停车了的点的等级,于是从没有停车的点向停车的点连边。

  然后可以确定出一张图,在图上跑拓扑序,顺便就能递推出每个点的等级了。

  问题是建图时最坏是$n^3$的复杂度,但是我们发现每个点总是一段连续的点连向它。

  于是想到用线段树优化建图,这东西比较神奇,一般长这样:

  P1983 车站分级第2张

  其实比较简单,就是在建树的时候维护一下子节点和父节点的边关系(注意两棵树边的方向不同),然后每次建图直接由一棵树的区间向一个虚点连边,再由该虚点向另一棵树的某一区间连边,具体实现视情况而定。

  本题的话是一段区间连向一个点,于是我们只要建一棵子节点连向父节点的线段树就够了,然后就每次都多建一个虚点(不能只用一个,否则边的直接相连关系会混乱),一段区间向虚点连边,再由虚点向所连点对应的叶子节点连边。

  最后就只需要跑一遍拓扑序,非叶子节点就直接由到达它的点更新,而叶子节点层数+1,处理出每个叶子节点最大的层数就是最少要的等级了。

  注意实现的细节比较多。

代码:

#include<bits/stdc++.h>
#define il inline
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=1505;
int h[N<<3],to[N*700],net[N*700],cnt,n,m,tp,stp[N],rd[N<<3],ar[N],f[N<<3];
bool nd[N<<3];
queue<int>q;

il int gi(){
    int a=0;char x=getchar();
    while(x<'0'||x>'9')x=getchar();
    while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
    return a;
}

il void add(int u,int v){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt,rd[v]++;}

il void build(int l,int r,int rt){
    tp=max(tp,rt);
    if(l==r){ar[l]=rt,nd[rt]=1;return;}
    int m=l+r>>1;
    add(rt<<1,rt),build(lson);
    add(rt<<1|1,rt),build(rson);
}

il void update(int L,int R,int l,int r,int rt){
    if(L>R)return;
    if(L<=l&&R>=r){add(rt,tp);return;}
    int m=l+r>>1;
    if(L<=m) update(L,R,lson);
    if(R>m) update(L,R,rson);
}

il void bfs(){
    For(i,1,tp) if(!rd[i]) q.push(i),f[i]=nd[i];
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=h[u];i;i=net[i]){
            rd[to[i]]--;
            f[to[i]]=max(f[u]+nd[to[i]],f[to[i]]);
            if(!rd[to[i]]) q.push(to[i]);
        }
    }
}

int main(){
    n=gi(),m=gi();
    build(1,n,1);
    int tot,ans=0;
    while(m--){
        tot=gi();tp++;
        For(i,1,tot) stp[i]=gi();
        For(i,1,tot-1) add(tp,ar[stp[i]]),update(stp[i]+1,stp[i+1]-1,1,n,1);
        add(tp,ar[stp[tot]]);
    }
    bfs();
    For(i,1,n) ans=max(ans,f[ar[i]]);
    cout<<ans;
    return 0;
}

免责声明:文章转载自《P1983 车站分级》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[原创]Emmagee V2.4工具使用介绍Python命名规范下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

Idea常用插件整合

官方网站:https://plugins.jetbrains.com/plugin/228-sql-query-plugin6.IdeaVim基于IntelliJ的Vim仿真插件。注意:如果打开WebInspector,那么CSS/JavaScript同步和元素高亮显示不起作用“pluginisdebuggingthistab”信息栏的可用性问题官方网站:h...

mysql之排序查询

高级文章目录3:排序查询功能:1.按单个字段排序案例1:查询员工信息,要求工资从高到低排序2.为排序添加筛选条件案例1:部门编号˃=90的员工信息,按员工编号降序排序案例2:部门编号˃=90的人员信息,按输入时间排序。按表达式排序案例1:按年薪显示员工信息和年薪4按别名排序案例1按年薪升序查询员工信息5.按函数(长度)排序案例1查询员工姓名并按姓名长度减少...

axios 学习文档

Axios是一个基于承诺的HTTP库,可以在浏览器和node.js中使用。执行POST请求axis.POST.then。接住执行多个并发请求函数getUserAccount(){returnaxios.get;}函数getUserPermissions(){returnaxios.get;}全部承诺。然后axios API可以通过传递相关配置来请求axios...

微信分享之分享图片/分享图标不能显示

微信分享的分享图标/图片无法显示,主要是由于以下几个问题:1.确保分享界面调用成功,分享路径正确。2.确保共享图片的路径不使用中文或全半角字符。3.确保副本不包含敏感字符,如红包和收据。当共享接口未能成功加载时,将发生错误。在页面的前面使用隐藏的div来放置要制作缩略图的图片。记住,不能直接隐藏图片。style=“display:noen”,如果没有,则使用...

mysql状态查看 QPS/TPS/缓存命中率查看

showglobalstatusslike'Com_ commit';showstatslike“无缓冲池读取%”;Thread_cache_Hits=(1-Thread_created/connections)*100%(8)锁定状态mysql&gt;showstatslike“Binlog_缓存%”;...

jenkins之部署、启动、关闭

jenkins可以通过内置的应用服务器或者借助其他应用服务器启动目录1、启动jenkins2、关闭jenkins3、重启jenkins4、重新加载jenkins配置信息前言:部署jenkins应用,是要安装java的,最新版本的jenkins是需要按照1.8版本的jdk,不然启动不了。...