• 最短路径算法


    floyd

     Floyd算法是一个经典的动态规划算法。用通俗的语言来描述的话,首先我们的目标是寻找从点i到点j的最短路径。从动态规划的角度看问题,我们需要为这个目标重新做一个诠释(这个诠释正是动态规划最富创造力的精华所在)

          从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离

    typedef struct          
    {        
        char vertex[VertexNum];                                //顶点表         
        int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表         
        int n,e;                                               //图中当前的顶点数和边数         
    }MGraph; 
    
    void Floyd(MGraph g)
    {
       int A[MAXV][MAXV];
       int path[MAXV][MAXV];
       int i,j,k,n=g.n;
       for(i=0;i<n;i++)
          for(j=0;j<n;j++)
          {   
                 A[i][j]=g.edges[i][j];
                path[i][j]=-1;
           }
       for(k=0;k<n;k++)
       { 
            for(i=0;i<n;i++)
               for(j=0;j<n;j++)
                   if(A[i][j]>(A[i][k]+A[k][j]))
                   {
                         A[i][j]=A[i][k]+A[k][j];
                         path[i][j]=k;
                    } 
         } 
    }

    dijkstra

    const int  MAXINT = 32767;
    const int MAXNUM = 10;
    int dist[MAXNUM];
    int prev[MAXNUM];
    
    int A[MAXUNM][MAXNUM];
    
    void Dijkstra(int v0)
    {
        bool S[MAXNUM];                                  // 判断是否已存入该点到S集合中
          int n=MAXNUM;
        for(int i=1; i<=n; ++i)
        {
            dist[i] = A[v0][i];
            S[i] = false;                                // 初始都未用过该点
            if(dist[i] == MAXINT)    
                  prev[i] = -1;
            else 
                  prev[i] = v0;
         }
         dist[v0] = 0;
         S[v0] = true;   
        for(int i=2; i<=n; i++)
        {
             int mindist = MAXINT;
             int u = v0;                               // 找出当前未使用的点j的dist[j]最小值
             for(int j=1; j<=n; ++j)
                if((!S[j]) && dist[j]<mindist)
                {
                      u = j;                             // u保存当前邻接点中距离最小的点的号码 
                      mindist = dist[j];
                }
             S[u] = true; 
             for(int j=1; j<=n; j++)
                 if((!S[j]) && A[u][j]<MAXINT)
                 {
                     if(dist[u] + A[u][j] < dist[j])     //在通过新加入的u点路径找到离v0点更短的路径  
                     {
                         dist[j] = dist[u] + A[u][j];    //更新dist 
                         prev[j] = u;                    //记录前驱顶点 
                      }
                  }
         }
    }
  • 相关阅读:
    CF
    求最长反链 || Dilworth 定理
    APIO 2020 补题记录
    CF vp 记录
    虚树
    LCT 学习
    平衡树
    poly
    关于此博客
    题解 P5021【NOIP2018】 【赛道修建】
  • 原文地址:https://www.cnblogs.com/dynas/p/7001615.html
Copyright © 2020-2023  润新知