【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

3

HINT

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

Source

Day2

 

 

【分析】

  题意就是求最短路的最长交。

  我们先做两次最短路求出最短路树(其实是拓扑图),然后交边给值,然后我再跑一遍最长路就好了。

 

  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 }
View Code

 

2017-03-05 16:01:53

posted @ 2017-03-05 15:55  konjak魔芋  阅读(174)  评论(0编辑  收藏  举报