• P2149 Elaxia的路线


    P2149 Elaxia的路线

    题意简述: 在一个n(n<=1500)个点的无向图里找两对点之间的最短路径的最长重合部分,即在保证最短路的情况下两条路径的最长重合长度(最短路不为一)

    • 思路:
    • 两边dij,第一遍最短路,第二遍在保证最短路的情况下让重合路径长度最长的先出队
    • 代码:
    #include <cstdio>
    #include <iostream>
    #include <queue>
    #include <cctype>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define res register int 
    inline int read()
    {
    	int x=0,f=1; char ch;
    	while(!isdigit(ch=getchar()))if(ch=='-')f=-1;
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return f*x;
    }
    
    const int N=1500+10,M=N*N*2;
    int x1,y1,x2,y2,n,m,tot=1;
    
    struct node{
    	int x,y;//xΪ×î¶Ì·³¤¶È£¬yΪ×ÖغÏ·¾¶³¤¶È 
    	bool operator >(const node &n2) const{return x==n2.x?y<n2.y:x>n2.x;}
    	bool operator <(const node &n2) const{return x==n2.x?y>n2.y:x<n2.x;}//СÓÚ ->¸üÓÅ
    	node(int _x=0,int _y=0) : x(_x),y(_y){}
    	bool operator ==(const node &n2) const{return x==n2.x&&y==n2.y;}
    	node operator +(const node &n2) const{return node(x+n2.x,y+n2.y);} 
    }edge[M],dis[M];
    int ver[M],nxt[M],head[N],vis[N];
    
    inline void add(int x,int y,int z)
    {
    	ver[++tot]=y; nxt[tot]=head[x]; head[x]=tot; edge[tot]=node(z,0);
    }
    	
    struct point{
    	int p; node d;
    	bool operator <(const point &n2) const{return d>n2.d;}
    	point(int _p=0,node _d=node(0,0)) : p(_p),d(_d) {}
    };
    
    inline void dij(int s)
    {
    	priority_queue <point> q;
    	for(res i=1 ; i<=n ; ++i) dis[i]=node(0x3f3f3f3f,0),vis[i]=0;
    	dis[s]=node(0,0); q.push(point(s,dis[s]));
    	while(q.size())
    	{
    		point now=q.top(); q.pop();
    		int x=now.p;
    		if(vis[x]) continue; vis[x]=1;
    		for(res i=head[x] ; i ; i=nxt[i])
    		{
    			int y=ver[i];
    			if(dis[y]>dis[x]+edge[i])
    			{
    				dis[y]=dis[x]+edge[i];
    				q.push(point(y,dis[y]));
    			}
    		}
    	}
    }
    
    void dfs(int x)
    {
    	for(res i=head[x] ; i ; i=nxt[i])
    	{
    		int y=ver[i];
    		if(dis[y]+edge[i]==dis[x])
    		{
    			edge[i].y+=edge[i].x; edge[i^1].y+=edge[i].x;
    			dfs(y);
    		}
    	}
    }
    
    int main()
    {
    	n=read(); m=read();
    	x1=read(); y1=read(); x2=read(); y2=read();
    	for(res i=1 ; i<=m ; ++i)
    	{
    		int x=read(),y=read(),z=read(); add(x,y,z); add(y,x,z);
    	}
    	dij(x1); dfs(y1); dij(x2); 
    	printf("%d
    ",dis[y2].y);
    	return 0;
    }
    

      

  • 相关阅读:
    2020.11.5收获
    代码大全2阅读笔记11~1
    2020.11.4收获
    2020.11.3收获
    2020.11.2收获
    Java学习10.21(javaweb对输入信息进行验证1)
    Java学习10.20(使用 form 元素)
    Java学习10.18——Javaweb常用表单元素
    Java学习10.17(新课程添加)
    Java学习10.11
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10616178.html
Copyright © 2020-2023  润新知