题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=4489

题解

感觉又被骗了。看这道题的 AC 人数不多,以为是一道很好的题目。结果发现是一个非常一般的最短路啊。

第一问的话,相当于同一个集合内的点可以瞬移,不需要花钱。于是可以每条线路建一个点,把每个站点向所在线路连边,边权为 \(0\);每条道路向站点连边,边权为 \(1\)。显然从 \(S\) 到 \(T\) 的最短路就是第一问的答案。最短路可以通过 01bfs 实现。

然后第二问的话,也可以继续建图来做。但是有一个更方便的做法。我们可以通过第一问得到的最短路给每一条线路和每个站点分层。然后对于同一层,枚举每一条线路,用这条线路上低一层的点来更新本层的点。(更新可以通过前后缀最大值来实现)


代码如下。

#include<bits/stdc++.h>
#include<tr1/unordered_map> #define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b , 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b , 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I>
inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 3e5 + 50000 + 7;
const int M = 3e5 + 7;
const int INF = 0x3f3f3f3f; int n, m, nod, S, T, hd, tl;
int dis[N], p[N], mxt[N], mxt2[N], pre[N], suf[N];
std::deque<int> q;
std::tr1::unordered_map<std::string, int> mp;
std::vector<int> v[N];
char tmp[50]; struct Edge { int to, ne; } g[N * 6]; int head[N], tot;
inline void addedge(int x, int y) { g[++tot].to = y, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y) { addedge(x, y), addedge(y, x); } inline void build() {
for (int i = 1; i <= n; ++i) {
int len = v[i].size();
for (int j = 0; j < len; ++j) adde(i + m, v[i][j]);
}
} inline void bfs() {
q.push_back(S);
memset(dis, -1, sizeof(dis)), dis[S] = 0;
while (!q.empty()) {
int x = q.front(); q.pop_front();
if (x <= m) {
for fec(i, x, y) if (!~dis[y]) dis[y] = dis[x] + 1, q.push_back(y);
} else for fec(i, x, y) if (!~dis[y]) dis[y] = dis[x], q.push_front(y);
}
} inline bool cmp(const int &x, const int &y) { return dis[x + m] < dis[y + m]; }
inline void work() {
build();
bfs();
for (int i = 1; i <= n; ++i) p[i] = i;
std::sort(p + 1, p + n + 1, cmp);
int r = 0;
while (r < n && dis[p[r + 1] + m] <= 0) ++r;
for (int i = 1; i <= n; ++i) {
int l = r + 1;
while (r < n && dis[p[r + 1] + m] == i) ++r;
for (int j = l; j <= r; ++j) {
int id = p[j], len = v[id].size();
pre[0] = suf[len + 1] = -INF;
for (int k = 0; k < len; ++k) pre[k + 1] = std::max(pre[k] + 1, dis[v[id][k]] == i - 1 ? mxt[v[id][k]] : -INF);
for (int k = len - 1; ~k; --k) suf[k + 1] = std::max(suf[k + 2] + 1, dis[v[id][k]] == i - 1 ? mxt[v[id][k]] : -INF);
for (int k = 0; k < len; ++k) if (dis[v[id][k]] == i) smax(mxt[v[id][k]], std::max(pre[k + 1], suf[k + 1]));
}
}
printf("%d\n", dis[T]);
printf("%d\n", mxt[T]);
} inline void init() {
read(n), read(m);
for (int i = 1; i <= m; ++i) scanf("%s", tmp), mp[tmp] = i;
for (int i = 1; i <= n; ++i) {
int l;
read(l);
while (l--) scanf("%s", tmp), v[i].pb(mp[tmp]);
}
scanf("%s", tmp), S = mp[tmp];
scanf("%s", tmp), T = mp[tmp];
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj4489 [Jsoi2015]地铁线路 最短路的更多相关文章

  1. 「JSOI2015」地铁线路

    「JSOI2015」地铁线路 传送门 第一问很简单:对于每条线路建一个点,然后所有该条线路覆盖的点向它连边,权值为 \(1\) ,然后它向所有线路上的点连边,权值为 \(0\) . 然后,跑一边最短路 ...

  2. ylbtech-SubwayNav(地铁线路导航)-数据库设计

    ylbtech-DatabaseDesgin:ylbtech-SubwayNav(地铁线路导航)-数据库设计 DatabaseName:SubwayNav(地铁线路导航) Type:线路导航 1.A, ...

  3. d3.js 绘制北京市地铁线路状况图(部分)

    地铁线路图的可视化一直都是路网公司的重点,今天来和大家一起绘制线路图.先上图. 点击线路按钮,显示相应的线路.点击线路图下面的站间按钮(图上未显示),上报站间故障. 首先就是制作json文件,这个文件 ...

  4. CSU 1808 地铁(最短路变形)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 题意: Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站, ...

  5. 牛客小白月赛6 I 公交线路 最短路 模板题

    链接:https://www.nowcoder.com/acm/contest/136/I来源:牛客网 题目描述 P市有n个公交站,之间连接着m条道路.P市计划新开设一条公交线路,该线路从城市的东站( ...

  6. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. 湖南省第十二届大学生计算机程序设计竞赛 F 地铁 多源多汇最短路

    1808: 地铁 Description Bobo 居住在大城市 ICPCCamp. ICPCCamp 有 n 个地铁站,用 1,2,…,n 编号. m 段双向的地铁线路连接 n 个地铁站,其中第 i ...

  9. CSU 1808 - 地铁 - [最短路变形]

    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808 Time limit: 5000 ms Memory limit: 13107 ...

随机推荐

  1. CKEDITOR Copying images from word

    自动导入Word图片,或者粘贴Word内容时自动上传所有的图片,并且最终保留Word样式,这应该是Web编辑器里面最基本的一个需求功能了.一般情况下我们将Word内容粘贴到Web编辑器(富文本编辑器) ...

  2. CSS入门基础学习二

    我们下午继续学习CSS的入门基础,搬上你的小板凳赶快进入吧! 一.背景(background) Background-color:背景颜色 background-image (背景图片) backgr ...

  3. 循序渐进实现仿QQ界面(三):界面调色与控件自绘

    本篇讲述如何进行界面调色.界面调色一般有两种方法,调色板和HSL色彩变换.调色板局限于256色,这里不采用,因此用HSL色彩变换实现.首先要了解一下什么是HSL色彩空间,完整且详尽的知识请到维基百科去 ...

  4. [CSP-S模拟测试110]题解

    也许是最后一篇了. A.最大或 不错的签到题. 对于二进制位来说,高位的一个1比低位的所有1的贡献总和还要大. 显然,$r$必选,因为$r$中所有1的相对考前.那么考虑如何构造另一个数. 首先$l$和 ...

  5. xsxsxsxsxsxsxsxs

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  6. Cadence 学习

    记录学习Cadence的资料 Cadence 16.6软件             链接: http://pan.baidu.com/s/1mgwSeYs 密码: jemk 于博士视频教程(15.7版 ...

  7. scrapy-redis debug视频

    前言 在上一篇笔记说过会录个视频帮助理解里面的类方法,现在视频来了.只录了debug scheduler.py里面的类方法,还有spiders.py里面的类方法差不多,就不说了,自己动手丰衣足食.限于 ...

  8. web接口开发基础知识-什么是web接口?

    比如我们访问百度的首页,输入的url地址是:https://www.baidu.com/ 那么当我们在浏览器地址栏中输入url,敲回车后,发生了什么事情?怎么就能通过1个url地址就能看到百度的首页了 ...

  9. Jexus web server V5.1 安装配置要点

    一.Jexus简介:Jexus web server for linux 是一款基于.NET兼容环境,运行于Linux/unix操作系统之上,以支持ASP.NET为核心功能的高性能WEB服务器.Jex ...

  10. EL表达式(二)运算符

    运算符"."和"[]": "."能做的"[]"也能做,"[]"能做的"."不一定 ...