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 ≤ ≤ 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
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,输入数据保证没有重边和自环。
分别以x1,y1,x2,y2为起点,做4次SPFA
分别算出dist[1~4][x]
那么我们可以找到他们各自最短路中相同的边
只要同时满足:
dist[1][u]+w(u,v)+dist[2][v]=dist[1][y1]
dist[3][u]+w(u,v)+dist[4][v]=dist[3][y2]
那么就说明,这条边同时处于两人的最短路上
然后将这些边建一个新图,可以保证无环
最后拓扑排序求出最长的链
但是,这道题隐藏了一个情况:
从y2~x2的w**与从x1~y1的Elaxia在边上相遇,也就是相向而行走一条边,也算共同走了这一条
也就是说,我们要将w**起点终点反转,重新建边和拓扑
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
struct Node
{
int next,to,dis;
}edge[],edge2[];
int head[],num,head2[],num2,dist[][],f[],n,d[],ans,m;
int s1,s2,t1,t2;
bool vis[];
void add(int u,int v,int w)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
edge[num].dis=w;
}
void add_Top(int u,int v,int w)
{
num2++;
edge2[num2].next=head2[u];
head2[u]=num2;
edge2[num2].to=v;
edge2[num2].dis=w;
}
void SPFA(int S,int T,int p)
{int i;
queue<int>Q;
memset(dist[p],/,sizeof(dist[p]));
dist[p][S]=;
Q.push(S);
while (Q.empty()==)
{
int u=Q.front();
Q.pop();
vis[u]=;
for (i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if (dist[p][v]>dist[p][u]+edge[i].dis)
{
dist[p][v]=dist[p][u]+edge[i].dis;
if (vis[v]==)
{vis[v]=;
Q.push(v);
}
}
}
}
}
void Top_sort()
{int i;
queue<int>Q;
memset(f,,sizeof(f));
for (i=;i<=n;i++)
if (d[i]==) Q.push(i),f[i]=;
while (Q.empty()==)
{
int u=Q.front();
Q.pop();
ans=max(ans,f[u]);
for (i=head2[u];i;i=edge2[i].next)
{
int v=edge2[i].to;
d[v]--;
f[v]=max(f[v],f[u]+edge2[i].dis);
if (d[v]==)
{
Q.push(v);
}
}
}
}
int main()
{int i,u,v,w,j;
cin>>n>>m;
cin>>s1>>t1>>s2>>t2;
for (i=;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
SPFA(s1,t1,);
SPFA(t1,s1,);
SPFA(s2,t2,);
SPFA(t2,s2,);
for (i=;i<=n;i++)
{
for (j=head[i];j;j=edge[j].next)
{
int v=edge[j].to;
if (dist[][i]+edge[j].dis+dist[][v]!=dist[][t1]) continue;
if (dist[][i]+edge[j].dis+dist[][v]!=dist[][t2]) continue;
add_Top(i,v,edge[j].dis);
d[v]++;
}
}
Top_sort();
SPFA(t2,s2,);
SPFA(s2,t2,);
memset(d,,sizeof(d));
memset(head2,,sizeof(head2));
for (i=;i<=n;i++)
{
for (j=head[i];j;j=edge[j].next)
{
int v=edge[j].to;
if (dist[][i]+edge[j].dis+dist[][v]!=dist[][t1]) continue;
if (dist[][i]+edge[j].dis+dist[][v]!=dist[][s2]) continue;
add_Top(i,v,edge[j].dis);
d[v]++;
}
}
Top_sort();
cout<<ans;
}