• 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
    ",ans);
    }
    
  • 相关阅读:
    vi 的使用,很详细
    Linux文件的打包与压缩
    Linux初学者学习资料
    正确的关机方法: sync, shutdown, reboot, halt, poweroff, init
    Linux命令下,cp,rm,mv命令的使用
    Linux的文件权限(简单易懂)
    FireBug与FirePHP
    Git进一步学习
    jQuery插件开发
    人生就如做项目
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/12673340.html
Copyright © 2020-2023  润新知