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
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**起点终点反转,重新建边和拓扑
1 #include2 #include 3 #include 4 #include 5 #include 6 using namespace std; 7 struct Node 8 { 9 int next,to,dis; 10 }edge[2000001],edge2[2000001]; 11 int head[2001],num,head2[2001],num2,dist[5][2001],f[2001],n,d[2001],ans,m; 12 int s1,s2,t1,t2; 13 bool vis[2001]; 14 void add(int u,int v,int w) 15 { 16 num++; 17 edge[num].next=head[u]; 18 head[u]=num; 19 edge[num].to=v; 20 edge[num].dis=w; 21 } 22 void add_Top(int u,int v,int w) 23 { 24 num2++; 25 edge2[num2].next=head2[u]; 26 head2[u]=num2; 27 edge2[num2].to=v; 28 edge2[num2].dis=w; 29 } 30 void SPFA(int S,int T,int p) 31 { int i; 32 queue Q; 33 memset(dist[p],127/3,sizeof(dist[p])); 34 dist[p][S]=0; 35 Q.push(S); 36 while (Q.empty()==0) 37 { 38 int u=Q.front(); 39 Q.pop(); 40 vis[u]=0; 41 for (i=head[u];i;i=edge[i].next) 42 { 43 int v=edge[i].to; 44 if (dist[p][v]>dist[p][u]+edge[i].dis) 45 { 46 dist[p][v]=dist[p][u]+edge[i].dis; 47 if (vis[v]==0) 48 {vis[v]=1; 49 Q.push(v); 50 } 51 } 52 } 53 } 54 } 55 void Top_sort() 56 { int i; 57 queue Q; 58 memset(f,0,sizeof(f)); 59 for (i=1;i<=n;i++) 60 if (d[i]==0) Q.push(i),f[i]=0; 61 while (Q.empty()==0) 62 { 63 int u=Q.front(); 64 Q.pop(); 65 ans=max(ans,f[u]); 66 for (i=head2[u];i;i=edge2[i].next) 67 { 68 int v=edge2[i].to; 69 d[v]--; 70 f[v]=max(f[v],f[u]+edge2[i].dis); 71 if (d[v]==0) 72 { 73 Q.push(v); 74 } 75 } 76 } 77 } 78 int main() 79 { int i,u,v,w,j; 80 cin>>n>>m; 81 cin>>s1>>t1>>s2>>t2; 82 for (i=1;i<=m;i++) 83 { 84 scanf("%d%d%d",&u,&v,&w); 85 add(u,v,w); 86 add(v,u,w); 87 } 88 SPFA(s1,t1,1); 89 SPFA(t1,s1,2); 90 SPFA(s2,t2,3); 91 SPFA(t2,s2,4); 92 for (i=1;i<=n;i++) 93 { 94 for (j=head[i];j;j=edge[j].next) 95 { 96 int v=edge[j].to; 97 if (dist[1][i]+edge[j].dis+dist[2][v]!=dist[1][t1]) continue; 98 if (dist[3][i]+edge[j].dis+dist[4][v]!=dist[3][t2]) continue; 99 add_Top(i,v,edge[j].dis);100 d[v]++;101 }102 }103 Top_sort();104 SPFA(t2,s2,3);105 SPFA(s2,t2,4);106 memset(d,0,sizeof(d));107 memset(head2,0,sizeof(head2));108 for (i=1;i<=n;i++)109 {110 for (j=head[i];j;j=edge[j].next)111 {112 int v=edge[j].to;113 if (dist[1][i]+edge[j].dis+dist[2][v]!=dist[1][t1]) continue;114 if (dist[3][i]+edge[j].dis+dist[4][v]!=dist[3][s2]) continue;115 add_Top(i,v,edge[j].dis);116 d[v]++;117 }118 }119 Top_sort();120 cout<