最短路--Dijkstra&&Floyed&&SPFA

最短路径是一个很常见的问题,这里有3种方法,可供参考。

一.Dijkstra
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int a[101][3]; double c[101]; bool b[101]; double f[101][101]; int n,i,j,k,x,y,m,s,e; double minl; double maxx = 1e30; int main() { cin >> n; for (i = 1; i <= n; i++) cin >> a[i][1] >> a[i][2]; for (i = 1; i <= n; i++) for(j = 1; j <= n; j++) f[i][j] = maxx; cin >> m; for (i = 1; i <= m; i++) { cin >> x >> y; f[x][y] = f[y][x] = sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2)); } cin>>s>>e; for(int i = 1;i <= n;i++) { c[i] = f[s][i]; } memset(b,false,sizeof(b)); b[s] = true; c[s] = 0; for(int i = 1;i <= n;i++) { minl = maxx; k = 0; for(int j = 1;j <= n;j++) { if(b[j] == false && c[j] < minl)//没走过的路程最小的点 { minl = c[j]; k = j; } } if(k == 0) break; b[k] = true; for(int j = 1;j <= n;j++) //将所以能变的点最小路程全变了 { if(c[k] + f[k][j] < c[j]) c[j] = c[k] + f[k][j]; } } printf("%.2lf",c[e]); return 0; }
二.Floyed
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; double f[100][100]; int a[100][3]; int m,n,x,y,r,s,e; int main() { memset(f,127,sizeof(f)); cin>>n; for(int i = 1;i <= n;i++) { cin>>a[i][1]>>a[i][2]; } cin>>m; for(int i = 1;i <= m;i++) { cin>>x>>y; f[y][x] = f[x][y] = sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2)); } cin>>s>>e; for(int k = 1;k <= n;k++) { for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { if(f[i][j] > f[i][k] + f[k][j] && i != j && i != k && j != k) f[i][j] = f[i][k] + f[k][j]; } } } printf("%.2lf",f[s][e]); return 0; } /* 5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 5 1 5 */
三.SPFA
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,p,c,i,j,x,y,t,min1,head,tail,tot,u;
int a[801][801],b[501],dis[801],num[801],w[801][801];
queue <int> team;
bool exist[801];
int main()
{
    cin>>n>>p>>c;
    for(i=1;i<=p;i++)
    {
        b[i]=0;
        num[i]=0;
        for(j=1;j<=p;j++)
            w[i][j]=0x7fffffff/3;
    }
    for(i = 1;i <= n;i++)
        cin>>b[i];
    for(i=1;i<=c;i++)                                      //邻接矩阵存储
    {
        cin>>x>>y>>t;
        w[x][y] = t;
        a[x][++num[x]] = y;
        a[y][++num[y]] = x;
        w[y][x] = w[x][y];
    }
    min1=0x7fffffff/3;
    for(i=1;i<=p;i++)
    {
        for(j=1;j<=p;j++) dis[j]=0x7fffffff/3;                      //队列数组初始化
        memset(exist,false,sizeof(exist));                   //exist标志初始化
        dis[i]=0;
        exist[i]=true;
        team.push(i);
        while(!team.empty())
        {
            u = team.front();
            team.pop();
            exist[u] = true;
            for(int j = 1;j <= num[u];j++)
            {
                if(dis[a[u][j]] > dis[u] + w[u][a[u][j]])
                {
                    dis[a[u][j]] = dis[u] + w[u][a[u][j]];
                    if(!exist[a[u][j]])
                    {
                        team.push(a[u][j]);
                        a[u][j] = true;
                    }
                }
            }
        }
        tot=0;
        for(j=1;j<=n;j++)
        tot+=dis[b[j]];
        if (tot<min1) min1=tot;
    }
    cout<<min1;
    return 0;
}

 

posted @ 2018-02-01 21:09  DukeLv  阅读(175)  评论(0编辑  收藏  举报