BZOJ1880: [Sdoi2009]Elaxia的路线(最短路)

1880: [Sdoi2009]Elaxia的路线

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 2049  Solved: 805

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1880

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

题解:

由于题目中有两个起点和终点,我们直接从每一个点出发跑一遍最短路。由于范围只有1500,所以我们可以直接枚举两个点,然后根据这两个点来计算维护一下答案就好了。

具体看代码吧,证明应该还是比较简单的。因为如果从s1出发到i点的最短路记做d1,从t1到j点的最短路记作d2,他们之间的最短路距离为d,那么说明i和j之间的最短路为d-d1-d2

如果此时s2,t2对于i,j两点同样满足上面的等式,即d'-d1'-d2'为i,j两点之间的最短路,那么说明这时i,j之间的最短路即为公共路径。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int M = 4000005,N = 1505 ;
int n,m;
int s1,s2,t1,t2;
struct Edge{
    int u,v,w,next ;
}e[M];
int tot;
int head[N],d[4][N],vis[N];
struct node{
    int u;
    ll d;
    bool operator < (const node &A)const{
        return d>A.d;
    }
};
void adde(int u,int v,int w){
    e[tot].v=v;e[tot].w=w;e[tot].next=head[u];head[u]=tot++;
}
void Dijkstra(int s,int id){
    priority_queue <node> q;memset(d[id],INF,sizeof(d[id]));
    memset(vis,0,sizeof(vis));d[id][s]=0;
    q.push(node{s,0});
    while(!q.empty()){
        node cur = q.top();q.pop();
        int u=cur.u;
        if(vis[u]) continue ;
        vis[u]=1;
        for(int i=head[u];i!=-1;i=e[i].next){
            int v=e[i].v;
            if(d[id][v]>d[id][u]+(ll)e[i].w){
                d[id][v]=d[id][u]+(ll)e[i].w;
                q.push(node{v,d[id][v]});
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(false);cin.tie(0);
    cin>>n>>m;
    cin>>s1>>t1>>s2>>t2;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        adde(u,v,w);adde(v,u,w);
    }
    Dijkstra(s1,0);Dijkstra(t1,1);
    Dijkstra(s2,2);Dijkstra(t2,3);
    int mn1=d[0][t1],mn2=d[2][t2];
    //cout<<mn1<<" "<<mn2<<endl;
    int ans = 0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j) continue ;
            int need = mn1-d[0][i]-d[1][j];
            if(mn2-d[2][i]-d[3][j]==need||mn2-d[2][j]-d[3][i]==need){
                ans=max(ans,need);
            }
        }
    }
    cout<<ans;
    return 0;
}

 

posted @ 2019-03-04 21:21  heyuhhh  阅读(114)  评论(0编辑  收藏  举报