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);
}

猜你喜欢

转载自www.cnblogs.com/naruto-mzx/p/12673340.html