题目传送门

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. redis学习 --Hash

    一:我们可以将Redis中的Hash类型看成具有String Key和String Value的map容器.所以该类型非常适合于存储值对象的信息.如Username.Password和Age等.如果H ...

  2. 未能加载文件或程序集 ICSharpCode.SharpZipLib

    Ui调用Webservice ,Webservice调用Bl BL中明明有那个dll文件 后来发现是webservice里面没有 在附加调试的时候,断点在bl层中

  3. Axios 安卓4.4不兼容的问题

    问题:Vue在使用Axios做接口请求时,如果是安卓4.4系统会发生报错,原因是安卓4.4不支持ES6的Promise语法 解决方案: 1.安装: npm install babel-polyfill ...

  4. PHP垃圾回收深入理解

    转摘于http://www.cnblogs.com/lovehappying/p/3679356.html PHP是一门托管型语言,在PHP编程中程序员不需要手工处理内存资源的分配与释放(使用C编写P ...

  5. HDU 5179 beautiful number (数位dp / 暴力打表 / dfs)

    beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. js/jq 小功能函数

    1.点击复制内容到剪贴板 function copyToClip(str) { var save = function(e) { e.clipboardData.setData('text/plain ...

  7. 牛客提高D6t2 破碎的序列

    分析 我们不难发现对于偶数的情况只要相邻两个数不相等即可 而对于奇数的情况只要中间恰好隔一个数的两个数不相等即可 于是我们又dp[i][0/1]表示考虑到第i位,这一位和它后面离它最近的一个确定的数是 ...

  8. druid spring监控配置

    方法一: <bean id="seckillServiceImpl" class="org.seckill.service.impl.SeckillServiceI ...

  9. WPF国际化方式1之资源文件

    先看效果吧,个人觉得由于MVVM模式的UI响应属性变化的特殊机制,资源文件和内存数据都是国际化不错的选择. 1.首先准备两个资源文件用来做中文和英文的转换使用,将程序中需要转换语言都弄成两个版本,分别 ...

  10. js-jssdk微信H5选择多张图片预览并上传(兼容ios,安卓,已测试)

    值得注意的是: 1.在微信H5中选择图片运用:wx.chooseImage,成功后返回:  res.localIds用于上传图片使用    上传图片:wx.uploadImage. 2.上传图片的时候 ...