luogu P2149 [SDOI2009]Elaxia的路线 |最短路+建最短路图+卡常数
题目描述
最近,Elaxia 和 w** 的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们必须合理地安排两个人在一起的时间。
Elaxia 和 w** 每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。
现在已知的是 Elaxia 和 w** 所在的宿舍和实验室的编号以及学校的地图:
地图上有 n 个路口,m 条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。
输入格式
第一行两个正整数 n,m,表示点数和边数。
第二行四个正整数 x_1,y_1,x_2,y_2,分别表示 Elaxia 的宿舍和实验室及 w** 的宿舍和实验室的标号。
接下来 m 行,每行三个整数 u,v,w,表示 u,v之间有一条边,需要 w 的时间经过。
输出格式
一行一个整数表示答案。(即最长公共路径的长度)
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read(){
int x=0; char c=getchar();
while(c<'0'||c>'9')c=getchar();
while('0'<=c&&c<='9'){ x=(x<<1)+(x<<3)+(c^48); c=getchar(); }
return x;
}
const int N=1510,M=10*N*N;
int nxt[M],head[N],go[M],cost[M],tot;
inline void add(int u,int v,int w){
nxt[++tot]=head[u];head[u]=tot;go[tot]=v;cost[tot]=w;
nxt[++tot]=head[v];head[v]=tot;go[tot]=u;cost[tot]=w;
}
struct node{
int u,d;
inline bool operator<(const node& rhs)const{
return d>rhs.d;
}
};
priority_queue<node>q;
int n,m,dis1[N],dis2[N],dis3[N],dis4[N],dis[N];
inline void dj(int s){
memset(dis,0x7f,sizeof(dis));
dis[s]=0; q.push((node){s,0});
while(q.size()){
int u=q.top().u;
int d=q.top().d;
q.pop();
if(d!=dis[u])continue;
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(dis[v]>dis[u]+cost[i]){
dis[v]=dis[u]+cost[i];
q.push((node){v,dis[v]});
}
}
}
}
inline void dj1(int s){
memset(dis1,0x7f,sizeof(dis1));
dis1[s]=0; q.push((node){s,0});
while(q.size()){
int u=q.top().u;
int d=q.top().d;
q.pop();
if(d!=dis1[u])continue;
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(dis1[v]>dis1[u]+cost[i]){
dis1[v]=dis1[u]+cost[i];
q.push((node){v,dis1[v]});
}
}
}
}
inline void dj2(int s){
memset(dis2,0x7f,sizeof(dis2));
dis2[s]=0; q.push((node){s,0});
while(q.size()){
int u=q.top().u;
int d=q.top().d;
q.pop();
if(d!=dis2[u])continue;
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(dis2[v]>dis2[u]+cost[i]){
dis2[v]=dis2[u]+cost[i];
q.push((node){v,dis2[v]});
}
}
}
}
inline void dj3(int s){
memset(dis3,0x7f,sizeof(dis3));
dis3[s]=0; q.push((node){s,0});
while(q.size()){
int u=q.top().u;
int d=q.top().d;
q.pop();
if(d!=dis3[u])continue;
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(dis3[v]>dis3[u]+cost[i]){
dis3[v]=dis3[u]+cost[i];
q.push((node){v,dis3[v]});
}
}
}
}
inline void dj4(int s){
memset(dis4,0x7f,sizeof(dis4));
dis4[s]=0; q.push((node){s,0});
while(q.size()){
int u=q.top().u;
int d=q.top().d;
q.pop();
if(d!=dis4[u])continue;
for(int i=head[u];i;i=nxt[i]){
int v=go[i];
if(dis4[v]>dis4[u]+cost[i]){
dis4[v]=dis4[u]+cost[i];
q.push((node){v,dis4[v]});
}
}
}
}
int x1,y1,x2,y2;
inline bool check1(int x,int y){
return(min(dis1[x]+dis3[y]+dis[y],dis1[y]+dis3[x]+dis[y])==dis1[y1]);
}
inline bool check2(int x,int y){
return(min(dis2[x]+dis4[y]+dis[y],dis2[y]+dis4[x]+dis[y])==dis2[y2]);
}
vector<int>a;
inline int abs(int x){if(x<0)return -x;else return x;}
struct S{
int u,v,w;
}e[N*N];
signed main(){
n=read(),m=read(),x1=read(),y1=read(),x2=read(),y2=read();
for(int i=1,u,v,w;i<=m;i++){
u=read(),v=read(),w=read();
add(u,v,w);
e[i]=(S){u,v,w};
}
dj1(x1); dj2(x2);
memset(nxt,0,sizeof(nxt)),tot=0;
memset(head,0,sizeof(head));
for(int i=1;i<=m;i++)
if(abs(dis1[e[i].u]-dis1[e[i].v])==e[i].w||abs(dis2[e[i].u]-dis2[e[i].v])==e[i].w)add(e[i].u,e[i].v,e[i].w);
dj3(y1); dj4(y2);
int ans=0;
for(int i=1;i<=n;i++)if(dis1[i]+dis3[i]==dis1[y1]&&dis2[i]+dis4[i]==dis2[y2])
a.push_back(i);
for(int i=0;i<a.size();i++){
dj(a[i]);
for(int j=i+1;j<a.size();j++)
if(ans<dis[a[j]]&&check1(a[i],a[j])&&check2(a[i],a[j]))
ans=max(ans,dis[a[j]]);
}
printf("%d\n",ans);
}
不以物喜,不以己悲