bzoj4489 [Jsoi2015]地铁线路 最短路
时间:2019-09-18
本文章向大家介绍bzoj4489 [Jsoi2015]地铁线路 最短路,主要包括bzoj4489 [Jsoi2015]地铁线路 最短路使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目传送门
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;
}
原文地址:https://www.cnblogs.com/hankeke/p/bzoj4489.html
- Premiere&After Effects的实时预览插件开发
- 委托与事件
- 一款批量修改AE模板的工具
- 深入线程
- 【插件开发】—— 2 插件入门
- 线程间通讯:WaitHandler使用实例及分析
- 域名Deskbike.com刚注册没多久就以五位数结拍
- 一起Polyfill系列:Function.prototype.bind的四个阶段
- winform实现拼图游戏
- 一起Polyfill系列:让Date识别ISO 8601日期时间格式
- Oracle 监听器无法启动(TNS-12537,TNS-12560,TNS-00507)
- Javascript Prototypes之旅(A Plain English Guide to JavaScript Prototypes译文)
- Python补充03 Python内置函数清单
- 不懂JQuery的孩子:自封装Ajax函数
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- CentOS7安装Git
- RocketMQ-环境搭建(单master模式-ubuntu版)
- 使用Web.xml配置SpringMvc(同时使用xml配置文件)
- 第七节:Activiti6.0——Task的变量使用
- 第八节:Activiti6.0——启动流程相关
- 第九节:Activiti6.0——ReceiveTask接收信号、中间信号捕获事件和中间消息捕获事件的流程推进
- SpringBoot——全局异常捕获和自定义异常
- RTSP协议视频平台EasyNVR接入到EasyNVS管理平台后无法显示RTMP及RTSP视频流地址问题
- SpringBoot——配置logback日志
- Istio 运维实战系列(2):让人头大的『无头服务』-上
- 第十节:Activiti6.0——四种Job工作的产生与管理
- 使用vue3.0,不需要build也可以
- 听说vue项目不用build也能用?
- 使用 Vue 3.0,你可能不再需要Vuex了
- MySQL InnoDB索引:存储结构