最短路(三种算法)

蒟蒻最近在不断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;
}

猜你喜欢

转载自www.cnblogs.com/zhouzhihao/p/10847108.html