蒟蒻最近在不断AK最短路
这篇博客就发一下最基础的三种做法(以后会发一篇升级版的)
1.大名鼎鼎的Floyd
2.Dijkstra
3.Bellman-Ford
就以这道题为例吧
(这道题数据苛(hen)刻(shui),不过代码已用大数据测过,不要怀疑算法的准确性)
注:三种算法我写在了一起
#include<bits/stdc++.h> using namespace std; struct node{ int x,y; }a[150]; double dis[150][150],f[150]; int n,m,s,t; void init_1() { cin>>n; for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y; cin>>m; memset(dis,0x7f,sizeof(dis)); for(int i=1;i<=m;i++) { int u,v; cin>>u>>v; dis[u][v]=sqrt(pow(a[u].x-a[v].x,2)+pow(a[u].y-a[v].y,2)); dis[v][u]=dis[u][v]; } cin>>s>>t; } void Floyd() { for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); printf("%.2lf",dis[s][t]); } bool used[150]; void Dj() { memset(f,0x7f,sizeof(f)); f[s]=0; for(int i=1;i<=n-1;i++) { int k=0; double minn=1e30; for(int j=1;j<=n;j++) if(!used[j] && f[j]<=minn) minn=f[j],k=j; if(k==0) break; used[k]=true; for(int j=1;j<=n;j++) if(!used[j]) f[j]=min(f[j],dis[j][k]+minn); } printf("%.2lf",f[t]); } double w[15000]; int u[15000],v[15000]; void init_2()//B-F算法的输入记录的是边,要特殊处理 { cin>>n; for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y; cin>>m; memset(f,0x7f,sizeof(f)); for(int i=1;i<=m;i++) { cin>>u[i]>>v[i]; w[i]=sqrt(pow(a[u[i]].x-a[v[i]].x,2)+pow(a[u[i]].y-a[v[i]].y,2)); } cin>>s>>t; } void Bellman_Ford() { f[s]=0; bool p=true;//一点小优化 for(int k=1;k<=n-1;k++) { for(int i=1;i<=m;i++) { if(f[v[i]]+w[i]<f[u[i]]) f[u[i]]=f[v[i]]+w[i],p=false; else if(f[u[i]]+w[i]<f[v[i]]) f[v[i]]=f[u[i]]+w[i],p=false; } if(p) break; } printf("%.2lf",f[t]); } int main() { init_2(); Bellman_Ford(); //或 //init_1(); //Dj(); return 0; }
原文:https://www.cnblogs.com/zhouzhihao/p/10847108.html