Title:
Give a path map of n points to find the secondary short circuit of points 1 to n
Solution:
1. Two shortest paths
d1 [], d2 [, n [] and d1 [] are calculated from 1 and N respectively.
Let the length of secondary short circuit be ans, traverse all sides, and let the current side be w[u,v]
If d1[u]+w[u,v]+d2[v] equals the shortest path from 1 to n, then w[u,v] is skipped on the shortest path.
Otherwise update ans=min(ans,d1[u]+w[u,v]+d2[v])
2. One dijkstra + update the shortest/shortest short circuit length at the same time
Update d1[],d2[] 4 while running dj
But I think there are too many details in the code. I don't like it very much.
Code with detailed comments
Two shortest paths:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #define set0(a) memset(a,0,sizeof(a)) #define set1(a) memset(a,-1,sizeof(a)) #define setinf(a) memset(a,inf,sizeof(a)) #define ll long long const int inf=0x3f3f3f3f; const int inn=0x80808080; using namespace std; const int maxm=2e5+5; int head[maxm],to[maxm],nt[maxm],w[maxm]; int mark[maxm]; int d1[maxm],d2[maxm]; int cnt; void add(int x,int y,int z){ cnt++;nt[cnt]=head[x];head[x]=cnt;to[cnt]=y,w[cnt]=z; cnt++;nt[cnt]=head[y];head[y]=cnt;to[cnt]=x,w[cnt]=z; } void init(){ set1(head); setinf(d1); setinf(d2); cnt=0; } void spfa(int st,int *d){ queue<int>q; q.push(st); set0(mark); mark[st]=1; d[st]=0; while(!q.empty()){ int x=q.front();; q.pop(); mark[x]=0; for(int i=head[x];i!=-1;i=nt[i]){ int v=to[i]; if(d[v]>d[x]+w[i]){ d[v]=d[x]+w[i]; if(!mark[v]){ mark[v]=1; q.push(v); } } } } } int main(){ init(); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } spfa(1,d1); spfa(n,d2); int ans=inf; for(int x=1;x<=n;x++){ for(int i=head[x];i!=-1;i=nt[i]){ int v=to[i]; int temp=d1[x]+d2[v]+w[i]; if(temp>d1[n]&&temp<ans){ ans=temp; } } } printf("%d\n",ans); return 0; }
dijkstra:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<queue> #define set0(a) memset(a,0,sizeof(a)) #define set1(a) memset(a,-1,sizeof(a)) #define setinf(a) memset(a,inf,sizeof(a)) #define ll long long const int inf=0x3f3f3f3f; const int inn=0x80808080; using namespace std; const int maxm=2e5+5; int head[maxm],to[maxm],nt[maxm],w[maxm]; int d1[maxm],d2[maxm]; int cnt; void add(int x,int y,int z){ cnt++;nt[cnt]=head[x];head[x]=cnt;to[cnt]=y,w[cnt]=z; cnt++;nt[cnt]=head[y];head[y]=cnt;to[cnt]=x,w[cnt]=z; } void init(){ set1(head); setinf(d1); setinf(d2); cnt=0; } void dj(int st){ priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q; d1[st]=0;//Note: This place can only initialize d1[st] and cannot initialize d2[st] q.push(make_pair(0,st)); while(!q.empty()){ int d=q.top().first; int x=q.top().second; q.pop(); if(d>d2[x])continue;//If the distance is longer than the short circuit, it can't be updated. for(int i=head[x];i!=-1;i=nt[i]){ int v=to[i]; int temp=d+w[i]; if(temp<d1[v]){ swap(d1[v],temp);//This place must be an exchange. Update the secondary short circuit with the old one. q.push(make_pair(d1[v],v)); } if(d1[v]<temp&&d2[v]>temp){ d2[v]=temp; q.push(make_pair(d2[v],v)); } } } } int main(){ init(); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ int a,b,c; scanf("%d%d%d",&a,&b,&c); add(a,b,c); } dj(1); printf("%d\n",d2[n]); return 0; }