这是一道次短路的板子题,和“路障”那一题不同的是,这个题的次短路不是严格大于最短路,所以连分类讨论都不用了,直接记录路径后删边求最短路即可。
下面给出参考程序:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<queue> 6 using namespace std; 7 double z,w[200005],dist[200005]; 8 double minn1,lesss,ans1=21374404; 9 int path[100000],cnt,num,n,m,x,y,v[200005],nxt[200005],head[200005],pre[200005],edge[200005],a[200005],b[200005]; 10 bool vis[200005]; 11 void add(int a,int b,double c) 12 { 13 v[++cnt]=b; 14 w[cnt]=c; 15 nxt[cnt]=head[a]; 16 head[a]=cnt; 17 } 18 void spfa(int s) 19 { 20 for(int i=1;i<=n;i++)dist[i]=336860180; 21 queue<int>q; 22 q.push(s); 23 dist[s]=0; 24 vis[s]=1; 25 while(!q.empty()) 26 { 27 int c=q.front(); 28 q.pop(); 29 vis[c]=0; 30 for(int i=head[c];i;i=nxt[i]) 31 { 32 int y=v[i]; 33 if(dist[y]>dist[c]+w[i]) 34 { 35 pre[y]=i;edge[y]=c; 36 dist[y]=dist[c]+w[i]; 37 if(!vis[y]) 38 { 39 q.push(y); 40 vis[y]=1; 41 } 42 } 43 } 44 } 45 } 46 double num1(int s,int q) 47 { 48 return sqrt((a[s]-a[q])*(a[s]-a[q])+(b[s]-b[q])*(b[s]-b[q])); 49 } 50 int main() 51 { 52 cin>>n>>m; 53 for(int i=1;i<=n;i++) 54 { 55 cin>>a[i]>>b[i]; 56 } 57 for(int i=1;i<=m;i++) 58 { 59 cin>>x>>y; 60 z=num1(x,y); 61 add(x,y,z); 62 add(y,x,z); 63 } 64 spfa(1); 65 minn1=dist[n]; 66 int now=n; 67 while(now!=1) 68 { 69 path[++num]=pre[now]; 70 now=edge[now]; 71 } 72 for(int i=1;i<=num;i++) 73 { 74 double s=w[path[i]]; 75 w[path[i]]=99999999; 76 spfa(1); 77 lesss=dist[n]; 78 ans1=min(ans1,lesss); 79 w[path[i]]=s; 80 } 81 if(ans1==21374404)cout<<"-1"; 82 else printf("%.2lf",ans1); 83 return 0; 84 }