【BZOJ 1880】 [Sdoi2009]Elaxia的路线 (最短路树)
1880: [Sdoi2009]Elaxia的路线
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
3HINT
对于30%的数据,N ≤ 100;
对于60%的数据,N ≤ 1000;
对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。Source
【分析】
题意就是求最短路的最长交。
我们先做两次最短路求出最短路树(其实是拓扑图),然后交边给值,然后我再跑一遍最长路就好了。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define Maxn 2010 9 #define Maxm 500010 10 #define INF 0xfffffff 11 12 int n; 13 14 struct node 15 { 16 int x,y,c,next; 17 }t[Maxm*2],tt[Maxm*3]; 18 int first[Maxn],len; 19 20 void ins(int x,int y,int c) 21 { 22 t[++len].x=x;t[len].y=y;t[len].c=c; 23 t[len].next=first[x];first[x]=len; 24 } 25 26 int x1,y1,x2,y2; 27 int st,ed; 28 29 queue<int > q; 30 31 int dis[3][Maxn]; 32 bool inq[Maxn]; 33 void spfa(int k) 34 { 35 while(!q.empty()) q.pop(); 36 memset(dis[k],63,sizeof(dis[k])); 37 memset(inq,0,sizeof(inq)); 38 inq[st]=1;q.push(st);dis[k][st]=0; 39 while(!q.empty()) 40 { 41 int x=q.front(); 42 for(int i=first[x];i;i=t[i].next) 43 { 44 int y=t[i].y; 45 if(dis[k][y]>dis[k][x]+t[i].c) 46 { 47 dis[k][y]=dis[k][x]+t[i].c; 48 if(!inq[y]) 49 { 50 q.push(y); 51 inq[y]=0; 52 } 53 } 54 } 55 q.pop();inq[x]=0; 56 } 57 } 58 59 void spfa2(int k) 60 { 61 while(!q.empty()) q.pop(); 62 // memset(dis[k],63,sizeof(dis[k])); 63 for(int i=1;i<=n;i++) dis[k][i]=-INF; 64 memset(inq,0,sizeof(inq)); 65 inq[st]=1;q.push(st);dis[k][st]=0; 66 while(!q.empty()) 67 { 68 int x=q.front(); 69 for(int i=first[x];i;i=t[i].next) 70 { 71 int y=t[i].y; 72 if(dis[k][y]<dis[k][x]+t[i].c) 73 { 74 dis[k][y]=dis[k][x]+t[i].c; 75 if(!inq[y]) 76 { 77 q.push(y); 78 inq[y]=0; 79 } 80 } 81 } 82 q.pop();inq[x]=0; 83 } 84 } 85 86 bool pd(int x) 87 { 88 if(dis[2][tt[x].y]+dis[1][tt[x].y]!=dis[1][y2]||dis[2][tt[x].x]+dis[1][tt[x].x]!=dis[1][y2]) return 0; 89 if(dis[1][tt[x].x]==dis[1][tt[x].y]+tt[x].c) return 1; 90 if(dis[1][tt[x].y]==dis[1][tt[x].x]+tt[x].c) return 1; 91 return 0; 92 } 93 94 int main() 95 { 96 int m; 97 scanf("%d%d",&n,&m); 98 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 99 len=0; 100 for(int i=1;i<=m;i++) 101 { 102 int x,y,c; 103 scanf("%d%d%d",&x,&y,&c); 104 ins(x,y,c);ins(y,x,c); 105 } 106 int ans1,ans2; 107 st=x1;spfa(0); 108 st=x2;spfa(1); 109 // st=y1;spfa(2); 110 st=y2;spfa(2); 111 // for(int i=1;i<=n;i++) printf("%d ",dis[0][i]);printf("\n"); 112 // for(int i=1;i<=n;i++) printf("%d ",dis[1][i]);printf("\n"); 113 st=n+1,ed=st+1; 114 memset(first,0,sizeof(first)); 115 int ln=len;len=0; 116 // tt=t; 117 for(int i=1;i<=ln;i++) tt[i]=t[i]; 118 for(int i=1;i<=ln;i++) 119 { 120 if(pd(i)&&dis[0][tt[i].y]==dis[0][tt[i].x]+tt[i].c) 121 { 122 ins(tt[i].x,tt[i].y,tt[i].c); 123 } 124 else if(dis[0][tt[i].y]==dis[0][tt[i].x]+tt[i].c) 125 { 126 ins(tt[i].x,tt[i].y,0); 127 } 128 } 129 // for(int i=1;i<=len;i++) printf("%d %d %d\n",t[i].x,t[i].y,t[i].c); 130 // return 0; 131 // ins(st,x1,0);ins(st,x2,0); 132 // ins(y1,ed,0);ins(y2,ed,0); 133 st=x1;ed=y1; 134 spfa2(0); 135 int ans=dis[0][ed]; 136 printf("%d\n",ans); 137 return 0; 138 }
2017-03-05 16:01:53