蒟蒻最近在不断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; for(int k=1;k<=n-1;k++) { bool p=true;//一点小优化 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; }
添加一个SPFA大法
添加时间:2019-5-17
#include<bits/stdc++.h> using namespace std; const int INTMAX=2147483647,MAX=500050; struct node{ int next; int to; int w; }a[MAX]; int f[MAX],head[10050]; int n,m,s,tot; bool b[10050]; queue<int> q; void add(int,int,int); void init() { cin>>n>>m>>s; memset(f,0x7f,sizeof(f)); for(int i=1;i<=m;i++) { int u,v,w; cin>>u>>v>>w; add(u,v,w); } } void add(int u,int v,int w) { tot++; a[tot].next=head[u]; a[tot].to=v; a[tot].w=w; head[u]=tot; } void print() { for(int i=1;i<=n;i++) if(f[i]<2e9) cout<<f[i]<<" "; else cout<<INTMAX<<" "; cout<<endl; } void SPFA() { f[s]=0; q.push(s); b[s]=true; while(!q.empty()) { int u; u=q.front(); q.pop(); b[u]=false; for(int i=head[u];i;i=a[i].next) { int v=a[i].to; if(f[v]>f[u]+a[i].w) { f[v]=f[u]+a[i].w; if(!b[v]) { b[v]=true; q.push(v); } } } // for(int i=1;i<=m;i++) // if(f[u[i]]+w[i]<f[v[i]]) // f[v[i]]=f[u[i]]+w[i],p=false; } print(); } int main() { init(); SPFA(); return 0; }