题目描述

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

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

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

解析

这题蛮好的,有助于更深入理解图论(可能吧),更有助于锻炼思维,如果可以的话,希望各位在独立思考出解法之前,能够多思考一下,反正我自己是想了一晚上。


首先分析题目,应该能很快发现每条线路对最终答案造成的影响。即,对于任意一条合法线路,其没有停靠的车站的等级恒小于其停靠过的车站的等级。

讲讲我的思路历程吧:

首先想到一种贪心,我们知道某条线路未停靠的点越少,其对最终答案的影响越小,但是经过尝试会发现这种贪心是有后效性的,不可行。

继而把思路引到图论上,图论的一个极其重要的作用大概就是维护一些抽象的关系以及限制条件,具体而明显地,比如并查集、网络流、差分约束等,其建模的本质是依靠题目中隐含的对象之间的某种关系。

那么这样想的话这题思路还是比较明显的,上面也提到过对于一条线路,其没有停靠的车站的等级恒小于其停靠过的车站的等级。这就是我们需要维护的关系。

这就很容易联想到拓扑排序,其维护的正是这种优先级大小关系。意即DAG中每一拓扑序的节点其等级大小是一致的。

我们感性地理解一下,题目告诉我们数据全部是满足要求的,实际上也就是告诉我们如果按照上面的思路建图,建出来必定是一个DAG(车站大小关系一定不会出现矛盾)。

题目要求最少划分的级别数,那我们只用使相邻拓扑序之间的节点等级差都只为1就可以了。

具体做法就是对于所有数据由等级小的车站向等级大的车站连有向边,再做一个拓扑排序就行了。

参考代码

代码略丑,实现比较简陋,如有疏漏望各位巨佬指出不足!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 1010
#define MOD 2520
#define E 1e-12
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
vector<int> g[N];
int head[N],tot,n,m,ing[N],dat[N][N],c[N];
bool v[N][N];
int main()
{
n=read(),m=read();
for(int i=1;i<=m;++i){
int s=read();dat[i][0]=s;
for(int j=1;j<=s;++j) dat[i][j]=read();//读入数据
}
for(int i=1;i<=m;++i){
int now=dat[i][1]+1;
for(int j=2;j<=dat[i][0];++j){
while(now<dat[i][j]){
for(int k=1;k<=dat[i][0];++k)
//维护节点之间大小关系
if(!v[now][dat[i][k]]) g[now].push_back(dat[i][k]),ing[dat[i][k]]++,v[now][dat[i][k]]=1;
now++;
//注意及时排除已经确定的关系,否则会T
}
now++;
}
}
int ans=0;
queue<int> q;
for(int i=1;i<=n;++i)//拓扑排序
if(ing[i]==0) q.push(i),c[i]=1;
while(q.size()){
int x=q.front();q.pop();
for(int i=0;i<g[x].size();++i){
int y=g[x][i];
if(--ing[y]==0) c[y]=c[x]+1,ans=max(ans,c[y]),q.push(y);
}
}
cout<<ans<<endl;
return 0;
}

写完这题的一点个人感想

对于图论,很多看似无法用图论去做的题,实际上隐藏了许多暗示,可以用图论去维护某些信息,进而求解。个人认为,图论是一个下限很低但是上限挺高的一门学问,其蕴含的骚操作还是很多的。

P1983 车站分级[拓扑]的更多相关文章

  1. 洛谷 P1983 车站分级 拓扑排序

    Code: #include<cstdio> #include<queue> #include<algorithm> #include<cstring> ...

  2. 洛谷P1983 车站分级

    P1983 车站分级 297通过 1.1K提交 题目提供者该用户不存在 标签图论贪心NOIp普及组2013 难度普及/提高- 提交该题 讨论 题解 记录 最新讨论 求帮忙指出问题! 我这么和(diao ...

  3. 洛谷P1983车站分级

    洛谷\(P1983\)车站分级(拓扑排序) 目录 题目描述 题目分析 思路分析 代码实现 题目描述 题目在洛谷\(P1983\)上 ​ 题目: 一条单向的铁路线上,依次有编号为 \(1, 2, -, ...

  4. P1983 车站分级 思维+拓扑排序

    很久以前的一道暑假集训的题,忘了补. 感觉就是思维建图,加拓扑排序. 未停靠的火车站,必然比停靠的火车站等级低,就可以以此来建边,此处注意用vis来维护一下,一个起点和终点只建立一条边,因为不这样的话 ...

  5. 洛谷 P1983 车站分级

    题目链接 https://www.luogu.org/problemnew/show/P1983 题目描述 一条单向的铁路线上,依次有编号为 1,2,…,n的 n个火车站.每个火车站都有一个级别,最低 ...

  6. 洛谷P1983车站分级题解

    题目 这个题非常毒瘤,只要还是体现在其思维难度上,因为要停留的车站的等级一定要大于不停留的车站的等级,因此我们可以从不停留的车站向停留的车站进行连边,然后从入度为0的点即不停留的点全都入队,然后拓扑排 ...

  7. LG1983 「NOIP2013」车站分级 拓扑排序

    问题描述 LG1983 题解 考虑建立有向边\((a,b)\),代表\(a\)比\(b\)低级. 于是枚举每一辆车次经过的车站\(x \in [l,r]\),如果不是车辆停靠的车站,则从\(x\)向每 ...

  8. 【洛谷P1983 车站分级】

    这题好像是个蓝题.(不过也确实差不多QwQ)用到了拓扑排序的知识 我们看这些这车站,沿途停过的车站一定比未停的车站的级别高 所以,未停靠的车站向已经停靠的车站连一条边,入度为0的车站级别就看做1 然后 ...

  9. P1983车站分级

    %%%rqy 传送 我们注意到题目中这段话: 既然大于等于x的站都要停,那么不停的站的级别是不是都小于x?(这里讨论在始发站和终点站以内的站(注意这里是个坑)) 我们可以找出每趟车没停的站,向所有停了 ...

随机推荐

  1. Jenkenis报错:该jenkins实例似乎已离线

    使用运行war的形式安装jenkins,因为伟大的墙出现,“该jenkins实例似乎已离线” 问题 解决方法: 1. 保留此离线页面,重新开启一个浏览器tab标签页 2.输入输入网址http://lo ...

  2. kexue shangwang

    根据实践,pptp.IPsec甚至OpenVPN等kexue上网法已经无法顺利翻越GFW.通过抓包可知,GFW会将pptp的握手期间的ack包吞掉,导致本地一直无法收到服务器端的响应.而OpenVPN ...

  3. NLP理解层次 --- 思维导图

  4. SpringBoot系列教程JPA之基础环境搭建

    JPA(Java Persistence API)Java持久化API,是 Java 持久化的标准规范,Hibernate是持久化规范的技术实现,而Spring Data JPA是在 Hibernat ...

  5. Java学习关注

    1.不去上课: 内部类的继承: https://blog.csdn.net/ruidianbaihuo/article/details/102092256 2.Matrix海 子 http://www ...

  6. [转帖]DCEP:中国自己的数字货币

    DCEP:中国自己的数字货币 https://cloud.tencent.com/developer/news/435883 前面我们讨论了Libra的革命性和局限性,接下来我想跟你聊一件重要的事,那 ...

  7. 封装关于金额计算的double工具类

    由于直接使用double类型的加减乘除,可能会出现不可预测的问题,精度丢失等等.在业务中,计算金额是一件很重要的事情. 可以直接使用BigDecimal类,进行加减乘除.相关BigDecimal类介绍 ...

  8. 装饰器login_required

    装饰器login_required将游客身份引导至登录页面,登录成功后跳转到目的页面 url.py path('login/',views.login), path('home/',views.hom ...

  9. hyper-v安装windows7

    win7镜像下载地址 http://msdn.itellyou.cn/ 该网站都是微软系列的正规软件 非常好用 在hyper-v 虚拟机安装windows系统时,到百度搜索了几个iso 都不好用 到h ...

  10. Java的基础类型笔记

    数据类型       大小 byte(字节)    1(8位) shot(短整型)       2(16位) int(整型)       4(32位) long(长整型)       8(32位) f ...