Description

最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

Input

第一行:两个整数N和M(含义如题目描述)。 第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ y2 ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。 接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。 出出出格格格式式式::: 一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)。

Output

一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

Sample Input

9 10
1 6 7 8
1 2 1
2 5 2
2 3 3
3 4 2
3 9 5
4 5 3
4 6 4
4 7 2
5 8 1
7 9 1

Sample Output

3

HINT

对于30%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。

题解

一开始看点数小,直接强行$SPFA$预处理出第一条路径,然后再$SPFA$第二条路径时记录答案。$TLE$...

  • 首先,分别从$x_1$,$y_1$,$x_2$,$y_2$为源点分别跑一次$SPFA$,记$dis[0][u]$,$dis[1][u]$,$dis[2][u]$,$dis[3][u]$分别为从$x_1$,$y_1$,$x_2$,$y_2$为起始点到点$u$的最短路径。

  • 构建出一个新的有向图,包含$x_1->y_1$和$x_2->y_2$的所有最短路上的边。判断一条边$u->v$是否在$x_1->y_1$的最短路上,就是判断$dis[1][u]+val(u,v)+dis[2][v]==dis[1][y1]$($val(u,v)$为边$u->v$的长度),如果为真,那么在最短路上,为假则不在最短路上。是否在$x_2->y_2$的最短路上同理。

  • 不过要注意一点,因为边的走向可能是$u->v$,也可能是$v->u$。所以,对于一条边必须判断两次(第一次为$u->v$,第二次为$v->u$)。

  • 最后,按照新图的拓扑序,在各个点之间进行递推,求得答案。
 //It is made by Awson on 2017.10.20
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define sqr(x) ((x)*(x))
#define y1 yy
using namespace std;
const int N = ; int n, m, x1, x2, y1, y2, u, v, c;
struct tt {
int to, cost, next;
bool color;
}edge[(N*N>>)+], g[(N*N>>)+];
int path[N+], top, path_g[N+], top_g;
int dist[][N+], ans, cnt[N+], in[N+];
struct node {
int x, val;
node (){
}
node (int _x, int _val) {
x = _x, val = _val;
}
}; void init(int u, int v, int c) {
g[++top_g].to = v;
g[top_g].cost = c;
g[top_g].next = path_g[u];
path_g[u] = top_g;
}
void add(int u, int v, int c) {
edge[++top].to = v;
edge[top].next = path[u];
edge[top].cost = c;
path[u] = top;
}
void topsort() {
queue<node>Q; while (!Q.empty()) Q.pop();
for (int i = ; i <= n; i++) if (!in[i]) Q.push(node(i, ));
while (!Q.empty()) {
int u = Q.front().x, val = Q.front().val; Q.pop();
ans = Max(ans, val);
for (int i = path_g[u]; i; i = g[i].next) {
int v = g[i].to; in[v]--; cnt[v] = Max(cnt[v], val+g[i].cost);
if (!in[v]) Q.push(node(v, cnt[v]));
}
}
}
void SPFA(int x, int t) {
bool vis[N+] = {}; vis[x] = ;
memset(dist[t], /, sizeof(dist[t])); dist[t][x] = ;
queue<int>Q; while (!Q.empty()) Q.pop(); Q.push(x);
while (!Q.empty()) {
int u = Q.front(); Q.pop(); vis[u] = ;
for (int i = path[u]; i; i = edge[i].next) {
int v = edge[i].to;
if (dist[t][v] > dist[t][u]+edge[i].cost) {
dist[t][v] = dist[t][u]+edge[i].cost;
if (!vis[v]) {
vis[v] = ; Q.push(v);
}
}
}
}
}
void work() {
scanf("%d%d%d%d%d%d", &n, &m, &x1, &y1, &x2, &y2);
for (int i = ; i <= m; i++) {
scanf("%d%d%d", &u, &v, &c);
add(u, v, c), add(v, u, c);
}
SPFA(x1, ); SPFA(y1, ); SPFA(x2, ), SPFA(y2, );
for (int u = ; u <= n; u++)
for (int i = path[u]; i; i = edge[i].next) {
int v = edge[i].to;
if (dist[][u]+dist[][v]+edge[i].cost != dist[][y1]) continue;
if (dist[][u]+dist[][v]+edge[i].cost != dist[][y2]) continue;
init(u, v, edge[i].cost); in[v]++;
}
topsort();
memset(path_g, , sizeof(path_g)); top_g = ;
memset(cnt, , sizeof(cnt));
for (int u = ; u <= n; u++)
for (int i = path[u]; i; i = edge[i].next) {
int v = edge[i].to;
if (dist[][u]+dist[][v]+edge[i].cost != dist[][y1]) continue;
if (dist[][u]+dist[][v]+edge[i].cost != dist[][y2]) continue;
init(u, v, edge[i].cost); in[v]++;
}
topsort();
printf("%d\n", ans);
}
int main() {
work();
return ;
}

[SDOI 2009]Elaxia的路线的更多相关文章

  1. 「SDOI 2009」Elaxia的路线

    发现自己这几天智商完全不在线-- 这道题的数据十分的水,怎样都可以艹过去-- 开始想了一个完全错误的算法,枚举一对点,判断这一对点是否同时在两条最短路上,是就用两点之间的路径更新答案.显然这样是错的: ...

  2. BZOJ-1880 Elaxia的路线 SPFA+枚举

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec Memory Limit: 64 MB Submit: 921 Solved: 354 [Submit][Sta ...

  3. BZOJ 1880: [Sdoi2009]Elaxia的路线( 最短路 + dp )

    找出同时在他们最短路上的边(dijkstra + dfs), 组成新图, 新图DAG的最长路就是答案...因为两人走同一条路但是不同方向也可以, 所以要把一种一个的s,t换一下再更新一次答案 ---- ...

  4. 【BZOJ1880】[Sdoi2009]Elaxia的路线(最短路)

    [BZOJ1880][Sdoi2009]Elaxia的路线(最短路) 题面 BZOJ 洛谷 题解 假装我们知道了任意两点间的最短路,那么我们怎么求解答案呢? 不难发现公共路径一定是一段连续的路径(如果 ...

  5. 洛谷 P2149 [SDOI2009]Elaxia的路线 解题报告

    P2149 [SDOI2009]Elaxia的路线 题目描述 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. Elaxia ...

  6. [BZOJ 1879][SDOI 2009]Bill的挑战 题解(状压DP)

    [BZOJ 1879][SDOI 2009]Bill的挑战 Description Solution 1.考虑状压的方式. 方案1:如果我们把每一个字符串压起来,用一个布尔数组表示与每一个字母的匹配关 ...

  7. P2149 Elaxia的路线

    P2149 Elaxia的路线 题意简述: 在一个n(n<=1500)个点的无向图里找两对点之间的最短路径的最长重合部分,即在保证最短路的情况下两条路径的最长重合长度(最短路不为一) 思路: 两 ...

  8. 【BZOJ 1880】 [Sdoi2009]Elaxia的路线 (最短路树)

    1880: [Sdoi2009]Elaxia的路线 Description 最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间. ...

  9. BZOJ1880: [Sdoi2009]Elaxia的路线(最短路)

    1880: [Sdoi2009]Elaxia的路线 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2049  Solved: 805 题目链接:https ...

随机推荐

  1. 第一次作业:来自一个奋斗的IT学子

    第一部分 结缘计算机 1.1你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 说起为何结缘了计算机,就得谈谈专业报考了,我觉得我的报考真是一个反面教科书了.由于高中以前每天只要想着 ...

  2. Beta冲刺随笔集合

    Beta冲刺随笔集合 项目Beta预备 Beta冲刺第一天 Beta冲刺第二天 Beta冲刺第三天 Beta冲刺第四天 Beta冲刺第五天 Beta冲刺第六天 Beta冲刺第七天 用户调查报告 Bet ...

  3. Beta冲刺 第五天

    Beta冲刺 第五天 1. 昨天的困难 1.昨天的困难主要是在类的整理上,一些逻辑理不清,也有一些类写的太绝对了,扩展性就不那么好了,所以,昨天的困难就是在重构上. 页面结构太凌乱,之前没有统筹好具体 ...

  4. 201621123040《Java程序设计》第十一周学习总结

    1.本周学习总结 1.1以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2.书面作业 2.1源代码阅读:多线程程序BounceThread 2.1.1BallRunnable类有什么用?为什 ...

  5. SciPy - 科学计算库(上)

    SciPy - 科学计算库(上) 一.实验说明 SciPy 库建立在 Numpy 库之上,提供了大量科学算法,主要包括这些主题: 特殊函数 (scipy.special) 积分 (scipy.inte ...

  6. github上传时出现error: src refspec master does not match any解决办法

    github上传时出现error: src refspec master does not match any解决办法 这个问题,我之前也遇到过,这次又遇到了只是时间间隔比较长了,为了防止以后再遇到类 ...

  7. Scrum 冲刺 第七日

    Scrum 冲刺 第七日 站立式会议 燃尽图 今日任务安排 项目发布说明 站立式会议 返回目录 燃尽图 返回目录 今日任务安排 返回目录 项目发布说明 本版本的新功能 不只是简单打地鼠,还有一些不能打 ...

  8. VS系列控制台闪退解决

    查阅--->总结-->实践--> 按红色标识走 ,完美解决! 至此,完美解决:原理不深究:

  9. java利用iTextWorker生成pdf

    使用itext生成pdf,在linux环境下,中文全部失踪,因为itext要在linux下支持中文字体需要引入itext-asian, 并添加一个字体类. public static class Pd ...

  10. (转载) Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)

    1 . 查看当天日期 select current_date(); 2. 查看当天时间 select current_time(); 3.查看当天时间日期 select current_timesta ...