NOIP2013普及组 车站分级
一条单向的铁路线上,依次有编号为 1, 2, …, n 的 n 个火车站。
每个火车站都有一个级别,最低为 1 级。
现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站 x 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)
例如,下表是 5 趟车次的运行情况。
其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求。
现有 m 趟车次的运行情况(全部满足要求),试推算这 n 个火车站至少分为几个不同的级别。
输入格式
第一行包含 2 个正整数 n,m,用一个空格隔开。
第 i+1 行(1≤i≤m)中,首先是一个正整数 si(2≤si≤n),表示第 i 趟车次有 si 个停靠站;接下来有 si 个正整数,表示所有停靠站的编号,从小到大排列。
每两个数之间用一个空格隔开。输入保证所有的车次都满足要求。
输出格式
输出只有一行,包含一个正整数,即 n 个火车站最少划分的级别数。
数据范围
1≤n,m≤1000
输入样例:
9 3 4 1 3 5 6 3 3 5 6 3 1 5 9
输出样例:
3
难度:中等 时/空限制:1s / 64MB 总通过数:2510 总尝试数:5347 来源:NOIP2013普及组 算法标签
解题思路:
由题意停靠的车站必然比非停靠的车站级别高
因此我们可以把一条线路中非停靠站和停靠站连一条权值为1的边:如样例:1,3,5,6.
所连接的边为:
因为题目保证一定有解所以该图肯定无环即为拓扑图。
但是这样建图的一个车次的边数为n * (1000 - n)(即非停靠点的点数n * 剩下的点数即停靠点的点数(1000 - n))最多有1000个车次即共需要建1000 * n * (1000 - n)条边,当n取500是上述式子取最大值即为1000 * 500 * 500这样肯定会tle所以不能这样建边。
这里有一个非常常用的算法,在非停靠点和停靠点之间建立一个虚拟点,非停靠点到虚拟点的权值定义为0,虚拟点到停靠点的权值定义为1:
如图:
这样的建边方式与上述的建边方式是等价的,因此所建立的边数从n * (1000 - n)变为n + 1000 - n; 因此边数最多为为1000 * (500 + 500)
#include <cstdio>
#include <cstring>
#include <iostream>using namespace std;const int N = 2010, M = 1000 * 1000 + 10;int n, m;
int d[N];//记录一个点的入度
bool st[N];//标记该点是否为停靠点
int dist[N];//dist[i]表示i这个点级别最低是多少
int q[N], hh, tt = -1;//拓扑排序数组
int h[N], e[M], ne[M], w[M],idx;//邻接表数组void add(int a, int b, int c)//邻接表模板
{d[b] ++ ;//b入度加1e[idx] = b;w[idx] = c;ne[idx] = h[a];h[a] = idx;idx ++ ;
}void topsort()//拓扑排序模板
{for (int i = 1; i <= n + m; i ++ )//要算上一个虚拟点if (!d[i]) q[++ tt] = i;while (hh <= tt){int t = q[hh ++ ];for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (-- d[j] == 0) q[++ tt] = j;}}
}int main()
{cin >> n >> m;memset(h, -1, sizeof h);for (int i = 1; i <= m; i ++ ){int cnt;scanf("%d", &cnt);memset(st, 0, sizeof st);int start = n, last = 1;//表示该车次从哪个车站开始到哪个车站结束while (cnt -- ){int stop;scanf("%d", &stop);st[stop] = true;//表示stop为停靠点start = min(start, stop);last = max(last, stop);}int ver = n + i;//在非停靠边和停靠边之间建立一个虚拟点for (int j = start; j <= last; j ++ )//从start开始到last结束if (st[j]) add(ver, j, 1);else add(j, ver, 0);}topsort();for (int i = 1; i <= n; i ++ ) dist[i] = 1;//每个车站级别最低为1,这里也可以建立一个虚拟源点,虚拟源点到每个点的权值为1for (int i = 0; i < n + m; i ++ )//加上虚拟源点{int j = q[i];for (int k = h[j]; k != -1; k = ne[k])dist[e[k]] = max(dist[e[k]], dist[j] + w[k]);//求最小的级别要用最长路,这里和差分约束的思想一样}int res = 0;for (int i = 1; i <= n; i ++ ) res = max(res, dist[i]);//找出所有符合条件的级别中最大的那个cout << res << endl;return 0;
}
若不了解这句话(dist[e[k]] = max(dist[e[k]], dist[j] + w[k]);)的同学可以看看差分约束的思想:
(1条消息) 《图论:差分约束算法详解 + 算法证明》+ 模板题:糖果_wsh1931的博客-CSDN博客
NOIP2013普及组 车站分级相关推荐
- P1983 [NOIP2013 普及组] 车站分级——拓扑排序+dp
[NOIP2013 普及组] 车站分级 题目描述 一条单向的铁路线上,依次有编号为 $1, 2, -, n $的 $n $个火车站.每个火车站都有一个级别,最低为 111 级.现有若干趟车次在这条线路 ...
- 洛谷 P1983 [NOIP2013 普及组] 车站分级
题目描述 一条单向的铁路线上,依次有编号为 1,2,-,n1, 2, -, n1,2,-,n的 nnn个火车站.每个火车站都有一个级别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下 ...
- P1983 [NOIP2013 普及组] 车站分级
题目描述 一条单向的铁路线上,依次有编号为 1, 2, -, n的 n个火车站.每个火车站都有一个级别,最低为 1级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x ...
- java 车站分级问题_【NOIP2013 普及组】车站分级
[NOIP2013 普及组]车站分级 一.题目 [NOIP2013 普及组]车站分级 时间限制: 1 Sec 内存限制: 128 MB 提交: 3 解决: 0 [提交][状态][讨论版] 题目描述 ...
- NOIP2013普及组 题解
T1 计数问题 题目描述 试计算在区间 1 到 n 的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1 到 11 中,即在 1.2.3.4.5.6.7.8.9.10.11 中, ...
- NOIP2013普及组 T2 表达式求值
OJ地址:洛谷P1981 CODEVS 3292 正常写法是用栈 1 #include<iostream> 2 #include<algorithm> 3 #include&l ...
- 信息学奥赛一本通 1961:【13NOIP普及组】计数问题 | 洛谷 P1980 [NOIP2013 普及组] 计数问题
[题目链接] ybt 1961:[13NOIP普及组]计数问题 洛谷 P1980 [NOIP2013 普及组] 计数问题 [题目考点] 1. 数字拆分 [解题思路] 遍历1~n的各个数字,对每个数字做 ...
- 信息学奥赛一本通 1962:【13NOIP普及组】表达式求值 | 洛谷 P1981 [NOIP2013 普及组] 表达式求值
[题目链接] ybt 1962:[13NOIP普及组]表达式求值 洛谷 P1981 [NOIP2013 普及组] 表达式求值 [题目考点] 栈 中缀表达式转后缀表达式,后缀表达式求值 中缀表达式求值 ...
- 洛谷——P1980 [NOIP2013 普及组] 计数问题
P1980 [NOIP2013 普及组] 计数问题 题目描述 试计算在区间 11 到 nn 的所有整数中,数字 xx(0\le x\le90≤x≤9)共出现了多少次?例如,在 11 到 1111 中, ...
- NOIP2013普及组复赛试题_计数问题
http://ybt.ssoier.cn:8088/problem_show.php?pid=1961 #include<iostream> using namespace std; in ...
最新文章
- 数学建模优化模型简单例题_数学建模之优化模型:存储模型
- 7.26T1四分图匹配
- vue中实现双向数据绑定原理,使用了Object.defineproperty()方法,方法简单
- ASP.NET MVC – 关于Action返回结果类型的事儿(上)
- (五)Oracle函数 序列 约束 索引
- plsql视图添加表字段_Oracle-单表多字段查询(不使用*)
- 【计算机科学基础】二进制加减法不用原码的原因
- linux shell中怎样批量修改文件名为 文件夹_文件名
- python卸载错误_卸载python后导致yum无法使用的解决办法 - Python - 服务器之家
- 将客户端将IE9强制为IE7
- javaweb调用第三方短信接口
- HTML5新增标签--canvas之绘制你画我猜
- PyAlgoTrade框架研究
- 笔记本电脑桌面的计算机图标不见了,笔记本电脑桌面显示没了怎么办呢
- poi解析excel(处理单元格公式)
- 蓝本(blueprint)
- 1987 三 比尔·哈利 Bill Haley
- POJ 1088 滑雪(输出对比)
- 2020年总结与展望
- c语言之打印输出图形