首页 > 其他分享 >第一周

第一周

时间:2024-07-15 14:29:35浏览次数:6  
标签:vexnum 第一周 ++ 路径 int MAXN printf

弗洛伊德基本思想
弗洛伊德算法作为求最短路径的经典算法,其算法实现相比迪杰斯特拉等算法是非常优雅的,可读性和理解都非常好。

基本思想:
弗洛伊德算法定义了两个二维矩阵:

矩阵D记录顶点间的最小路径
例如D[0][3]= 10,说明顶点0 到 3 的最短路径为10;
矩阵P记录顶点间最小路径中的中转点
例如P[0][3]= 1 说明,0 到 3的最短路径轨迹为:0 -> 1 -> 3。
它通过3重循环,k为中转点,v为起点,w为终点,循环比较D[v][w] 和 D[v][k] + D[k][w] 最小值,如果D[v][k] + D[k][w] 为更小值,则把D[v][k] + D[k][w] 覆盖保存在D[v][w]中。

概念是比较难理解的,我们来看图:

 

顶点名称和下标的对应
A B C D E F G
0 1 2 3 4 5 6

第2步:
以A为中间点,原D矩阵中,D[B][G]的值为INF,即不存在B->G的最小路径,但是通过A为中间点,D[B][A] + D[A][G] = 12 + 14 = 26 小于 D[B][G] = INF, 所以D[B][A] + D[A][G] 为 B -> G的最小值,因此覆盖D[B][G] 为 26。

第3步:
以B为中间点,第2步后的D矩阵中,D[A][C]的值为INF, 但是通过B,D[A][B] + D[B][C] = 12 + 10 = 22 小于 D[A][C] = INF,所以D[A][B] + D[B][C] 为 A->C的最小路径,覆盖D[A][C]的值为22, 以此类推。

第4步….

代码实现
我们就对上面的图进行弗洛伊德算法求最短路径,并且我们求A到D的最小路径,即v = 0, w = 3;
结构定义;

复制代码
typedef struct struct_graph{
    char vexs[MAXN];
    int vexnum;//顶点数 
    int edgnum;//边数 
    int matirx[MAXN][MAXN];//邻接矩阵 
} Graph;
复制代码

弗洛伊德算法:

复制代码
//这里是弗洛伊德算法的核心部分 
    //k为中间点 
    for(k = 0; k < G.vexnum; k++){
        //v为起点 
        for(v = 0 ; v < G.vexnum; v++){
            //w为终点 
            for(w =0; w < G.vexnum; w++){
                if(D[v][w] > (D[v][k] + D[k][w])){
                    D[v][w] = D[v][k] + D[k][w];//更新最小路径 
                    P[v][w] = P[v][k];//更新最小路径中间顶点 
                }
            }
        }
    }
复制代码

求A到D的最短路径:

复制代码
    v = 0;
    w = 3;
    //求 0 到 3的最小路径
    printf("\n%d -> %d 的最小路径为:%d\n", v, w, D[v][w]);
    k = P[v][w];
    printf("path: %d", v);//打印起点
    while(k != w){
        printf("-> %d", k);//打印中间点
        k = P[k][w]; 
    }
    printf("-> %d\n", w);
复制代码

完整代码:

复制代码
#include <stdio.h>
#include <stdlib.h>

#define MAXN 10 
#define INF = 1000

typedef struct struct_graph{
    char vexs[MAXN];
    int vexnum;//顶点数 
    int edgnum;//边数 
    int matirx[MAXN][MAXN];//邻接矩阵 
} Graph;

int pathmatirx[MAXN][MAXN];//记录对应点的最小路径的前驱点,例如p(1,3) = 2 说明顶点1到顶点3的最小路径要经过2 
int shortPath[MAXN][MAXN];//记录顶点间的最小路径值

void short_path_floyd(Graph G, int P[MAXN][MAXN], int D[MAXN][MAXN]){
    int v, w, k;
    //初始化floyd算法的两个矩阵 
    for(v = 0; v < G.vexnum; v++){
        for(w = 0; w < G.vexnum; w++){
            D[v][w] = G.matirx[v][w];
            P[v][w] = w;
        }
    }

    //这里是弗洛伊德算法的核心部分 
    //k为中间点 
    for(k = 0; k < G.vexnum; k++){
        //v为起点 
        for(v = 0 ; v < G.vexnum; v++){
            //w为终点 
            for(w =0; w < G.vexnum; w++){
                if(D[v][w] > (D[v][k] + D[k][w])){
                    D[v][w] = D[v][k] + D[k][w];//更新最小路径 
                    P[v][w] = P[v][k];//更新最小路径中间顶点 
                }
            }
        }
    }

    printf("\n初始化的D矩阵\n");
    for(v = 0; v < G.vexnum; v++){
        for(w = 0; w < G.vexnum; w++){
            printf("%d ", D[v][w]);
        }
        printf("\n");
    }

    printf("\n初始化的P矩阵\n");
    for(v = 0; v < G.vexnum; v++){
        for(w = 0; w < G.vexnum; w++){
            printf("%d", P[v][w]);
        }
        printf("\n");
    }

    v = 0;
    w = 3;
    //求 0 到 3的最小路径
    printf("\n%d -> %d 的最小路径为:%d\n", v, w, D[v][w]);
    k = P[v][w];
    printf("path: %d", v);//打印起点
    while(k != w){
        printf("-> %d", k);//打印中间点
        k = P[k][w]; 
    }
    printf("-> %d\n", w);
}

int main(){
    int v, w;
    Graph G;
    printf("请输入顶点数:\n");
    scanf("%d", &G.vexnum);
    printf("请输入初始矩阵值:\n");
    for(v = 0; v < G.vexnum; v++){
        for(w = 0; w < G.vexnum; w++){
            scanf("%d", &G.matirx[v][w]);
        }
    }
    printf("\n输入的矩阵值:\n");
    for(v = 0; v < G.vexnum; v++){
        for(w = 0; w < G.vexnum; w++){
            printf("%d ", G.matirx[v][w]);
        }
        printf("\n");
    }
    short_path_floyd(G, pathmatirx, shortPath);
}
复制代码

 

   

标签:vexnum,第一周,++,路径,int,MAXN,printf
From: https://www.cnblogs.com/kongxiangzeng/p/18303098

相关文章

  • 暑假第一周周报
    主要学习了二分算法:写了一些经典的二分算法;还写了一些和其他算法结合的二分:递归分治,题目:给一个数组{a},定义h(a,b)为在十进制下a+b与a的位数差,求和所有的h(ai,aj),0<i<j<n;不能暴力n方,用分治的思想,分解成最小的子问题求两个数的位数差,再层层往上归并,将后半段排序后,枚......
  • SMU Summer 2024 第一周周报 (zhaosang)
    学到了很多,不仅仅是学习方面的,在学校学跟在家寒假对比,天差地别吧。补题的过程中收获满满,最近练习二分三分,栈队列单调栈等习题,题目不简单,努力学习中。。打比赛也是,也有打的很惨的时候,我自己需要多总结找出原因,把短板补齐。总的来说,这个星期很累,但很爽!星期一:https://www.cnblogs......
  • hadoop第一周总结
    在Hadoop学习的第一个周,我经历了一段充实而又具有挑战性的学习过程。在这个过程中,我深入了解了Hadoop的基本概念、核心组件和工作原理。以下是我对本周学习的总结:首先,我开始了解Hadoop的概念和背景。Hadoop是一个开源的分布式存储和计算框架,旨在处理大规模数据集,并且具有高可靠性......
  • 暑假第一周周报
    这周除了个人赛外,还进行了线段树、数状数组的练习。刚开始训练的时候,对线段数和数状数组是缺乏理解,感觉非常非常难,但随着做了越来越多的题。感觉现在是掌握了其中一部分。刚开始学线段树,其中的懒标记感觉不是太会,于是就网上找了一些资料,把那个懒标记的相关知识点给学了一下。个人......
  • 暑期训练第一周周报
    总体学习情况这周的强度还是很大的,二分和简单数据结构的牛客题单还没有刷完,想着把补题放到第一位,然后后面慢慢补上那些没有做的题,比赛打得还是依旧很拉,不过没有关系,太阳照常升起,总会赢的。知识点模块1.Floyd算法用来求两点到达的最小代价,复杂度是O(n3)其实代码并不难记,可以说板......
  • 7.13(第一周周六)
    第一周,基于Ambari搭建了大数据分析平台,根据教程创建了三台Linux虚拟机。根据教程一点一点做,发现了很多问题,通过网上搜索资料解决了以后,顺利地搭建起了该平台,发现这块东西真的很难,主要是很抽象,不像之前学的搭建一个网站,写一款安卓软件,现在大数据这个东西看不见摸不着,而且我也没有Li......
  • 第一周学习总结
    开篇概述随着计算机网络基础设施的完善,社交网络和电商的发展以及物连网的推进,产生了越来越多的大数据,使得人工智能最近几年也有了长足的发展(可供机器学习的样本数据量足够大了),大数据的存储和处理也越来越重要,国家对此也比较重视(可上网搜索关键字“大数据白皮书”关键字,以了解详细......
  • 2024/07/13(暑假学习hadoop第一周总结)
    在本周的学习中,我构建了学习Hadoop所需的基础环境,这包括安装虚拟机VMware和部署CentOS操作系统。这些步骤是学习Hadoop开始,也为是深入学习Hadoop技术做好前置的准备工作。下面将详细介绍如何安装VMware和部署CentOS系统:首先,我们需要下载VMware软件并进行安装。在安装过程中,请务必......
  • 学习hadoop第一周
    刚开始接触Hadoop,我深感这一大数据处理框架的复杂与强大。Hadoop以其分布式存储和处理海量数据的能力,在业界享有盛誉,成为大数据领域的核心技术之一。在学习过程中,我首先遇到了Hadoop的架构理解难题。Hadoop采用主从架构,包括HDFS、YARN等核心组件,每个组件都有其独特的功能和相互之......
  • 第一周
    以下是Java的"Hello,World!"代码javaCopyCodepublicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.println("Hello,World!");}}类定义:publicclassHelloWorld{...}:这是一个类的定义。每个Java程序都至少有一个类。类名必须与文件名相......