题目链接:

​https://www.luogu.org/problem/P1491​

说明:

1:这道题目考的就是把第一遍跑的最短路径的途经边每次去掉一条,然后再跑最短路径,从中选择最短,即为要求的边,特别注意,有可能最终结果等于第一次的最短路径,因为最短路径不只一条,所以这道题目又不是严格意义上的求次短路径

2:参考博客:​​https://www.luogu.org/blog/Minamoto/solution-p1491​

因为我是java转的c++,所以,有一些细节就不是太熟练,在自己思路明确的情况下,参考了这一个博客,读自己的代码时,可以边看这一个博客,边读自己的代码,因为,比如函数spfa的调用所传的参数就是参考了这一个博客,然后巧妙的存下了,最短路径途径的边,和处理了后来的删边

1:spfa

#include <bits/stdc++.h>

using namespace std;
const int maxn=2e2+1,inf=0x3f3f3f3f;
vector<pair<int,double> >e[maxn];
int n,m,a,b,point[maxn][2],t,prev[maxn],ing[maxn];
double d[maxn],temp,c,ans=inf;

inline void spfa(int s,int f,int t)
{
for(int i=1;i<=n;i++)d[i]=inf;
memset(ing,0,sizeof(ing));
queue<int>q;
q.push(s);
d[s]=0;
ing[s]=1;
while(!q.empty())
{
int now=q.front();
q.pop();
ing[now]=0;
for(int i=0;i<e[now].size();i++)
{
int v=e[now][i].first;
if((f==now&&t==v)||(f==v&&t==now))
continue;
if(d[v]>d[now]+e[now][i].second)
{
d[v]=d[now]+e[now][i].second;
if(f==-1&&t==-1)prev[v]=now;
if(ing[v])
continue;
q.push(v);
ing[v]=1;
}
}
}
}

double edge(int i,int j)
{
return sqrt((point[i][0]-point[j][0])*(point[i][0]-point[j][0])+(point[i][1]-point[j][1])*(point[i][1]-point[j][1]));
}

int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>point[i][0]>>point[i][1];
for(int i=1;i<=m;i++)
{
cin>>a>>b;
c=edge(a,b);
e[a].push_back(make_pair(b,c));
e[b].push_back(make_pair(a,c));
}
spfa(1,-1,-1);
t=n;
while(prev[t]!=0)
{
temp=prev[t];
spfa(1,temp,t);
ans=min(ans,d[n]);
t=temp;
}
if(ans==inf)printf("-1");
else printf("%.2lf",ans);
return 0;
}

2:dijkstra

#include <bits/stdc++.h>

using namespace std;
const int maxn=2e2+1,inf=0x3f3f3f3f;
vector<pair<int,double> >e[maxn];
int n,m,a,b,point[maxn][2],t,prev[maxn];
double d[maxn],temp,c,ans=inf;

inline void dijkstra(int s,int f,int t)
{
for(int i=1;i<=n;i++)d[i]=inf;
priority_queue<pair<double,int> >q;
q.push(make_pair(-d[s],s));
d[s]=0;
while(!q.empty())
{
int now=q.top().second;
q.pop();
for(int i=0;i<e[now].size();i++)
{
int v=e[now][i].first;
if((f==now&&t==v)||(f==v&&t==now))
continue;
if(d[v]>d[now]+e[now][i].second)
{
if(f==-1&&t==-1)prev[v]=now;
d[v]=d[now]+e[now][i].second;
q.push(make_pair(-d[v],v));
}
}
}
}

double edge(int i,int j)
{
return sqrt((point[i][0]-point[j][0])*(point[i][0]-point[j][0])+(point[i][1]-point[j][1])*(point[i][1]-point[j][1]));
}

int main()
{
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>point[i][0]>>point[i][1];
for(int i=1;i<=m;i++)
{
cin>>a>>b;
c=edge(a,b);
e[a].push_back(make_pair(b,c));
e[b].push_back(make_pair(a,c));
}
dijkstra(1,-1,-1);
t=n;
while(prev[t]!=0)
{
temp=prev[t];
dijkstra(1,temp,t);
ans=min(ans,d[n]);
t=temp;
}
if(ans==inf)printf("-1");
else printf("%.2lf",ans);
return 0;
}