题目传送门

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. [HG]奋斗赛G

    T1 题目描述 安娜斯塔西娅喜欢去乌日扬迪安中央公园散步. 但她对简单的散步不感兴趣,于是她开始收集公园里的鹅卵石. 一开始,她决定收集所有她能在公园里找到的鹅卵石. 她只有两个口袋. 她能在每个口袋 ...

  2. C#中如何通过点击按钮切换窗口

    实现方法如下: 1.设计  首先在左侧放一个panel,右侧放一个panel(命名为pnlMain),调整大小,在左侧panel里放置两个按钮(多个按钮同理) 2.在按钮里面写方法 在[命名规范检查] ...

  3. form表单action带参数传递

    form表单action带参数传递function submit(){  var u = document.forms[0].elements["user"].value;  do ...

  4. php面试专题---16、MySQL创建高性能索引考点

    php面试专题---16.MySQL创建高性能索引考点 一.总结 一句话总结: 注意:只写精品 1.索引的基础? 类似书籍的目录:索引类似于书籍的目录,要想找到一本书的某个特定主题,需要先查找书的目录 ...

  5. Bing Advanced Search Tricks You Should Know

    Bing is one of the world's most popular search engines that has gained many fans with its ease of us ...

  6. django中的url控制

    1.django中的第一个控件:url控制  (路由分发) urls.py:请求路径与视图函数的之间的关系 步骤: 1.首先是要配置环境,   2.其次就是引路径   3.在视图的文件夹里面写相应的函 ...

  7. [转]Scikit-learn使用总结

    1 scikit-learn基础介绍 1.1 估计器(Estimator) 估计器,很多时候可以直接理解成分类器,主要包含两个函数: fit():训练算法,设置内部参数.接收训练集和类别两个参数. p ...

  8. Python笔记(十五)_异常处理

    try-except语句 try: 被检测代码 except Exception [as reason]: 出现异常后的处理代码 例: try: sum = 1+' f=open('未定义文件.txt ...

  9. python3 -tensorflow-dataset 之map函数 lambda隐函数的应用

    ###隐函数lanbda及map函数的应用实例 ''' lambda 参数1,参数2,参数3,...:表达式 ''' f = lambda x,y :x+y print(f(1,2)) ###输出3 ...

  10. JNDI配置笔记

    先在tomcat Context.xml配置文件中配置 <Resource name="jdbc/elifecrm" type="javax.sql.DataSou ...