zoukankan      html  css  js  c++  java
  • Floyd算法

    算法过程

      1,从任意一条单边路径开始。所有两点之间的距离是边的权,或者无穷大,如果两
    点之间没有边相连。
      2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己
    知的路径更短。如果是更新它。

    Floyd算法适用于APSP(All Pairs Shortest Paths),是一种动态规划算法,稠密图效果
    最佳,边权可正可负。此算法简单有效,由于三重循环结构紧凑,对于稠密图,效率要高
    于执行|V|次Dijkstra算法。


    改进和优化

      用来计算传递封包。
      计算闭包只需将Floyd中的f数组改为布尔数组,将加号改为and就可以了。


    #include<stdio.h>
    #include<stdlib.h>
    #define MAX_VERTEX_NUM 100 //最大顶点数
    #define MAX_INT 10000 //无穷大
    typedef int AdjType;
    typedef struct{
    int pi[MAX_VERTEX_NUM];//存放v到vi的一条最短路径
    int end;
    }PathType;
    typedef char VType; //设顶点为字符类型
    typedef struct{
    VType V[MAX_VERTEX_NUM]; //顶点存储空间
    AdjType A[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
    }MGraph;//邻接矩阵表示的图
    //Floyd算法
    //求网G(用邻接矩阵表示)中任意两点间最短路径
    //D[][]是最短路径长度矩阵,path[][]最短路径标志矩阵
    void Floyd(MGraph * G,int path[][MAX_VERTEX_NUM],int D[][MAX_VERTEX_NUM],int
    n){
    int i,j,k;
    for(i=0;i<n;i++){//初始化
    for(j=0;j<n;j++){
    if(G->A[i][j]<MAX_INT){//判断是否存在路径
    path[i][j]=j;
    }else{
    path[i][j]=-1;//或者一开始就初始化为-1,不能是零,因为a[0][0]j也为0
    }
    D[i][j]=G->A[i][j];
    }
    }

    for(k=0;k<n;k++){//进行n次试探
    for(i=0;i<n;i++){
    for(j=0;j<n;j++){
    if(D[i][j]>D[i][k]+D[k][j]){
    D[i][j]=D[i][k]+D[k][j];//取小者
    path[i][j]=path[i][k];//改Vi的后继
    }
    }
    }
    }
    }


    int main(){
    int i,j,k,v=0,n=6;//v为起点,n为顶点个数
    MGraph G;
    int path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//v到各顶点的最短路径向量
    int D[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//v到各顶点最短路径长度向量

    //初始化
    AdjType a[MAX_VERTEX_NUM][MAX_VERTEX_NUM]={
    {0,12,18,MAX_INT,17,MAX_INT},
    {12,0,10,3,MAX_INT,5},
    {18,10,0,MAX_INT,21,11},
    {MAX_INT,3,MAX_INT,0,MAX_INT,8},
    {17,MAX_INT,21,MAX_INT,0,16},
    {MAX_INT,5,11,8,16,0}
    };
    for(i=0;i<n;i++){
    for(j=0;j<n;j++){
    G.A[i][j]=a[i][j];
    }
    }

    Floyd(&G,path,D,6);

    for(i=0;i<n;i++){//输出每对顶点间最短路径长度及最短路径
    for(j=0;j<n;j++){
    printf("V%d到V%d的最短长度:",i,j);
    printf("%d\t",D[i][j]);//输出Vi到Vj的最短路径长度
    k=path[i][j];//取路径上Vi的后续Vk
    if(k==-1){
    printf("There is no path between V%d and V%d\n",i,j);//路径不
    存在
    }else{
    printf("最短路径为:");
    printf("(V%d",i);//输出Vi的序号i
    while(k!=j){//k不等于路径终点j时
    printf(",V%d",k);//输出k
    k=path[k][j];//求路径上下一顶点序号
    }
    printf(",V%d)\n",j);//输出路径终点序号
    }
    printf("\n");
    }
    }

    system("pause");
    return 0;
    }

  • 相关阅读:
    【Codeforces 349B】Color the Fence
    【Codeforces 459D】Pashmak and Parmida's problem
    【Codeforces 467C】George and Job
    【Codeforces 161D】Distance in Tree
    【Codeforces 522A】Reposts
    【Codeforces 225C】Barcode
    【Codeforces 446A】DZY Loves Sequences
    【Codeforces 429B】Working out
    【Codeforces 478C】Table Decorations
    【Codeforces 478C】Table Decorations
  • 原文地址:https://www.cnblogs.com/hxsyl/p/2443320.html
Copyright © 2011-2022 走看看