• 1342:【例4-1】最短路径问题


    1342:【例4-1】最短路径问题

     Floyed算法模板题

     Floyed算法

    1.计算图中任意两点间的最短路径

    2.适用于出现负边权

    3.算法描述:

      (1)初始化:点u,v如果有边相连,则dis[u][v]=w[u][v]

                              如果不相连,则dis[u][v]=0x7fffffff

      (2)  for ( int k=1 ; k<=n ; k++ )      //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 ] ) 
                               f [ i ] [ j ] = f [ i ] [ k ] + f [ k ] [ j ] ;

      (3)算法结束:dis[i][j]得出的就是从 i 到 j 的最短路径

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    int n,m,s,t,x,y;
    int a[101][3];
    double f[101][101];
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
          cin>>a[i][1]>>a[i][2];
        cin>>m;
    memset(f,
    0x7f,sizeof(f)); //先初始化为一个较大内容的数组 for(int 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>>t;
    for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j&&i!=k&&j!=k&&f[i][j]>f[i][k]+f[k][j]) f[i][j]=f[i][k]+f[k][j];
    printf(
    "%.2lf",f[s][t]); return 0; }

     Dijkstra算法 O(N*N)

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    int a[101][3];
    double c[101];
    bool b[101];
    double f[101][101];
    int n,m,x,y,k,s,e;
    double minl;
    double maxx=1e30;
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
          cin>>a[i][1]>>a[i][2];
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
          f[i][j]=maxx;    //f数组初始化最大值 
        cin>>m;
        for(int 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-1;i++)
        {
            minl=maxx;
            k=0;
            for(int j=1;j<=n;j++)  //查找可以更新的点
              if(!b[j]&&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;     
    
    }

     

     

  • 相关阅读:
    第一讲小结(位运算)
    新学期开始
    前缀表达式-怎样用空格分隔一个字符串
    计概期末前的小小总结
    动规作业-求数组不相邻元素之和的最大值
    网格-递归作业2-放苹果问题
    1025 数的划分(搜索和递推方法)
    网格-递归作业 集合里的乘法
    网格-递归作业 城堡问题
    去先导零的一个大坑
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/10745308.html
Copyright © 2020-2023  润新知