P2149 [SDOI2009]Elaxia的路线(最短路)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2149 [SDOI2009]Elaxia的路线(最短路)相关的知识,希望对你有一定的参考价值。
P2149 [SDOI2009]Elaxia的路线(最短路)
题意
求两对最短路的最长公共路径。
思路
结论是两对最短路的最长公共路径是一条链。
考虑跑 4 4 4次最短路求出每对起点和终点的最短路。
然后判断一条边是否在最短路上出现就可以:
d 1 [ u ] + w + d 2 [ v ] = d 1 [ e d ] d_1[u]+w+d_2[v]=d_1[ed] d1[u]+w+d2[v]=d1[ed]
d 1 d_1 d1是对于 s t st st的最短路, d 2 d_2 d2是对于 e d ed ed的最短路。
我们把一条边同时在 ( s t , e d ) , ( s t 1 , e d 1 ) (st,ed),(st_1,ed_1) (st,ed),(st1,ed1) 加入到新图,注意相遇也是算公共,所以要特判下反边是否也满足,然后进行重新建图。
我们建的是个有向图,所以可以跑 d p dp dp,记忆化搜索求出 d p u dp_u dpu以 u u u出发的最长路径。
时间复杂度: O ( m l o g n ) O(mlogn) O(mlogn)
// Problem: P2149 [SDOI2009]Elaxia的路线
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2149
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-08-17 10:00:40
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1505,M=1e6+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int n,m;
struct edge{
int to,nt,w;
}e[M<<1],e1[M<<1];
int h[N],h1[N],cnt,cnt1;
void add(int u,int v,int w){
e[++cnt]={v,h[u],w},h[u]=cnt;
e[++cnt]={u,h[v],w},h[v]=cnt;
}
bitset<N>bj;
void add1(int u,int v,int w){
e1[++cnt1]={v,h1[u],w},h1[u]=cnt1,bj[u]=bj[v]=1;
}
int d1[N],d2[N],d3[N],d4[N];
bitset<N>vis;
void dij(int st,int *d){
priority_queue<PII>q;
vis.reset();
memset(d,0x3f,sizeof d1);
d[st]=0,q.push({0,st});
while(!q.empty()){
int u=q.top().se;q.pop();
if(vis[u]) continue;vis[u]=1;
for(int i=h[u];i;i=e[i].nt){
int v=e[i].to,w=e[i].w;
if(!vis[v]&&d[v]>d[u]+w){
d[v]=d[u]+w;
q.push({-d[v],v});
}
}
}
}
int s1,t1,s2,t2;
int dp[N],ans;
int dfs(int u){
if(dp[u]) return dp[u];
for(int i=h1[u];i;i=e1[i].nt){
int v=e1[i].to,w=e1[i].w;
dp[u]=max(dp[u],dfs(v)+w);
}
ans=max(ans,dp[u]);
return dp[u];
}
int main(){
scanf("%d%d",&n,&m);
scanf("%d%d%d%d",&s1,&t1,&s2,&t2);
for(int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);add(u,v,w);
}
dij(s1,d1),dij(t1,d2),dij(s2,d3),dij(t2,d4);
for(int u=1;u<=n;u++)
for(int i=h[u];i;i=e[i].nt){
int v=e[i].to,w=e[i].w;
if(d1[u]+w+d2[v]==d1[t1]){
if(d3[u]+w+d4[v]==d3[t2]) add1(u,v,w);
if(d3[v]+w+d4[u]==d3[t2]) add1(v,u,w);
}
}
for(int i=1;i<=n;i++) if(bj[i]&&!dp[i]) dfs(i);
printf("%d\\n",ans);
return 0;
}
以上是关于P2149 [SDOI2009]Elaxia的路线(最短路)的主要内容,如果未能解决你的问题,请参考以下文章
洛谷—— P2149 [SDOI2009]Elaxia的路线