20200926模拟
T3,赶紧写完不然又忘了:$x$到$y$的最短路有两种情况
- 没有路过$s$到$t$的最短路上的点
- 路过$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 }