20200926模拟

T3,赶紧写完不然又忘了:$x$到$y$的最短路有两种情况

  1. 没有路过$s$到$t$的最短路上的点
  2. 路过$s$到$t$的最短路上的点,即$x$,$y$两点到同一条最短路的最近距离

实现:

$minn1$,$minn2$表示多条最短路上的一个点$u$到$s$这段区间内所有的点,距离$x$和$y$的最短距离

$dp1$[u],$dp2$[u]表示多条最短路上的一个点$u$到$t$这段区间内所有的点,距离$x$和$y$的最短距离

$dis_{1,2,3}$分别表示以$s$,$x$,$y$为源点的最短路

方程:

  • $minn$1 = $min$($dis2$[$u$],$minn1$),$minn2$ = $min$($dis3$[$u$],$minn2$);
  • $dp1$[$u$] = $min$($dp1$[$u$],$dis2$[$u$]);$dp2$[$u$] = $min$($dp2$[$u$],$dis3$[$u$]);
  • $ans$ = $min$($ans$,$min$($dp1$[$u$]+$minn2$,$dp2$[$u$]+$minn1$));

注意:保证答案中与$x$,$y$距离最短的两个点要在同一条最短路中,这个只能自己理解怎么保证了,虽然我一直在重复理解了一遍再看又不理解,然后又理解的过程

代码副本,转载雷同:

 1 #include <iostream>
 2 #include <algorithm> 
 3 #include <cstdio>
 4 #include <queue>
 5 #include <cstring>
 6 using namespace std;
 7 const int maxn=1e6+7;
 8 const int inf=1e9+7;
 9 int n,m,u,v,w,s,t,x,y;
10 struct node{
11     int to,next,w;
12 }ed[maxn];
13 int tot,head[maxn];
14 int dis1[maxn],dis2[maxn],dis3[maxn];
15 void add(int u,int to,int w){
16     ed[++tot].to=to;
17     ed[tot].w=w;
18     ed[tot].next=head[u];
19     head[u]=tot;
20 }
21 bool vis[maxn];
22 void Dij(int s,int *dis){
23     priority_queue<pair<int,int> >q;
24     q.push(make_pair(0,s));memset(vis,0,sizeof(vis));
25     for (int i = 1;i <= n;i++) dis[i]=2147483647;dis[s]=0;
26     while (!q.empty()){
27         int x=q.top().second;q.pop();
28         if (vis[x]) continue;
29         vis[x]=1;
30         for (int i =head[x];i;i=ed[i].next){
31             int to=ed[i].to;
32             if (dis[to]>dis[x]+ed[i].w){
33                 dis[to]=dis[x]+ed[i].w;
34                 q.push(make_pair(-dis[to],to));
35             }
36         }
37     }
38 }
39 int dp1[maxn],dp2[maxn],ans;
40 void dfs(int x,int minn1,int minn2){
41     if (vis[x]) return;
42     vis[x]=1;
43     minn1=min(dis2[x],minn1),minn2=min(dis3[x],minn2);
44     for(int i = head[x];i;i=ed[i].next){
45         int to=ed[i].to;
46         if (dis1[to]-dis1[x]!=ed[i].w) continue;
47         dfs(to,minn1,minn2);
48         dp1[x]=min(dp1[x],dp1[to]);dp2[x]=min(dp2[x],dp2[to]);
49     }
50     dp1[u] = min(dp1[x],dis2[x]);dp2[x] = min(dp2[x],dis3[x]);
51     ans = min(ans,min(dp1[x]+minn2,dp2[x]+minn1));
52 }
53 int main(){
54     scanf ("%d%d",&n,&m);
55     for(int i = 1;i <= m;i++){
56         scanf ("%d%d%d",&u,&v,&w);
57         add(u,v,w);add(v,u,w);
58     }
59     scanf ("%d%d%d%d",&s,&t,&x,&y);
60     Dij(s,dis1);Dij(x,dis2);Dij(y,dis3);
61     ans=dis2[y];
62     memset(vis,0,sizeof(vis));
63     for (int i = 1;i <= n;i++) dp1[i]=dp2[i]=inf;
64     dfs(t,inf,inf);
65     printf("%d",ans);
66     return 0;
67 }

 

原文地址:https://www.cnblogs.com/very-beginning/p/13736407.html