题意:
求一个无向图中,两个点对最短路的最长公共路径。
注意给出的x1,y1和x2,y2不一定是从x走到y,可以是y走到x。
做法:
首先无脑跑最短路QAQ..
事实上,我们要把以x1,y1,x2,y2为起点的最短路都跑出来。
然后对于一条边u,v,边权为w,假如dis[s-u]+dis[v-t]+w == dis[s-t],则u-v这条边是在s-t的最短路上的。
我们把同在x1-y1,x2-y2的最短路上的边取出来重新构图,在新图上跑一个拓扑求最长链即可。
当然由于可以从y走到x,所以再把x2,y2交换一下再做一次拓扑,取两次答案的最大值。
代码:
/*************************************************************
Problem: bzoj 1880 [Sdoi2009]Elaxia的路线
User: fengyuan
Language: C++
Result: Accepted
Time: 1148 ms
Memory: 54796 kb
Submit_Time: 2018-01-24 17:07:19
*************************************************************/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
inline ll read() {
char ch = getchar(); ll x = 0; int op = 1;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') op = -1;
for(; isdigit(ch); ch = getchar()) x = x*10+ch-'0';
return x*op;
}
inline void write(ll a) {
if(a < 0) putchar('-'), a = -a;
if(a >= 10) write(a/10); putchar('0'+a%10);
}
const int N = 1510;
int n, m, ans, cnt, s1, s2, t1, t2;
int head[N], head2[N], dis[5][N], dp[N], in[N];
bool vis[N];
struct edge {
int to, nxt, v;
edge() {}
edge(int x, int y, int z) { to = x, nxt = y, v = z; }
}e[N*N<<1];
inline void addedge(int x, int y, int z) { e[++ cnt] = edge(y, head[x], z); head[x] = cnt; }
inline void addedge2(int x, int y, int z) { e[++ cnt] = edge(y, head2[x], z); head2[x] = cnt; }
inline void spfa(int p, int s) {
queue<int> q; q.push(s); dis[p][s] = 0; memset(vis, 0, sizeof vis); vis[s] = 1;
while(!q.empty()) {
int u = q.front(); q.pop(); vis[u] = 0;
for(int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if(dis[p][v] > dis[p][u]+e[i].v) {
dis[p][v] = dis[p][u]+e[i].v;
if(!vis[v]) { vis[v] = 1; q.push(v); }
}
}
}
}
inline void tp() {
queue<int> q; memset(dp, 0, sizeof dp);
for(int i = 1; i <= n; i ++) if(!in[i]) q.push(i);
while(!q.empty()) {
int u = q.front(); q.pop(); ans = max(ans, dp[u]);
for(int i = head2[u]; i; i = e[i].nxt) {
int v = e[i].to; in[v] --;
dp[v] = max(dp[v], dp[u]+e[i].v);
if(!in[v]) q.push(v);
}
}
}
int main() {
n = read(), m = read(), s1 = read(), t1 = read(), s2 = read(), t2 = read();
for(int i = 1; i <= m; i ++) {
int x = read(), y = read(), z = read();
addedge(x, y, z); addedge(y, x, z);
} memset(dis, 0x3f, sizeof dis);
spfa(0, s1); spfa(1, t1); spfa(2, s2); spfa(3, t2);
for(int i = 1; i <= n; i ++)
for(int j = head[i]; j; j = e[j].nxt) {
int k = e[j].to;
if(dis[0][i]+dis[1][k]+e[j].v == dis[0][t1] && dis[2][i]+dis[3][k]+e[j].v == dis[2][t2]) {
addedge2(i, k, e[j].v); in[k] ++;
}
}
tp();
swap(dis[2], dis[3]); memset(head2, 0, sizeof head2); memset(in, 0, sizeof in);
for(int i = 1; i <= n; i ++)
for(int j = head[i]; j; j = e[j].nxt) {
int k = e[j].to;
if(dis[0][i]+dis[1][k]+e[j].v == dis[0][t1] && dis[2][i]+dis[3][k]+e[j].v == dis[2][s2]) {
addedge2(i, k, e[j].v); in[k] ++;
}
}
tp();
write(ans); puts("");
return 0;
}