首页 > 其他分享 >暑假第一周总结

暑假第一周总结

时间:2024-07-06 14:09:19浏览次数:16  
标签:总结 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/binglinll/p/18279752

相关文章

  • 暑假第二天
    7月四日完成了数据结构的第二个题目;老板的作息表,这是我的源代码#include<iostream>#include<cstdio>#include<string>#include<vector>#include<queue>#include<map>#include<algorithm>#include<math.h>usingnamespacestd;structnode{str......
  • 暑假第三天
    7月5日今天完成了数据结构第三题;寻找大富翁,下面是我的源代码#include<iostream>#include<vector>usingnamespacestd;constintmax_size=1000010;intnum[max_size];voidsift(int*num,intlow,inthigh){inti=low;intj=2*i;inttemp=num[i]......
  • 暑假第四天
    7月5日今天完成了二路归并排序,下面是我的源代码#include<iostream>usingnamespacestd;intn;int*a;//定义为指针,用于动态分配内存voidMerge(inta[],intt[],intlow,intmid,inthigh){inti=low,j=mid+1,k=low;while(i<=mid&&j<=high)......
  • js中数组方法总结
    改变原数组的方法有:栈方法push:数组末尾追加任意数量的元素,返回修改后数组的长度pop:数组末尾移除最后一项,返回移除的项队列方法unshift:数组前端添加任意个项并返回新数组的长度shift:移除数组中的第一项并返回改该项重排序方法sort:默认情况按照升序排列数组reserve:翻......
  • 2024年6月后2周重要的大语言模型论文总结:LLM进展、微调、推理和对齐
    本文总结了2024年6月后两周发表的一些最重要的大语言模型论文。这些论文涵盖了塑造下一代语言模型的各种主题,从模型优化和缩放到推理、基准测试和增强性能。LLM进展与基准1、BigCodeBench:BenchmarkingCodeGenerationwithDiverseFunctionCallsandComplexInstructions......
  • 暑假集训第五天
    并查集/最小生成树/Kruskal重构树专题TwoFamousCompanieshttps://www.luogu.com.cn/problem/solution/SP11579如果白边整体权值太小,我们就把所有白边的权值加上一个正值,让整体权值变大。反之,白边整体权值过大,我们就把所有白边的权值加上一个负值。让整体权值变小。我们把......
  • PTA题目集7-8的总结
    PTA题目集7-8的总结1.前言:2.设计与分析:3.踩坑心得:4.改进意见:5.总结1.前言:  PTA题目集7新增了互斥开关,窗帘,多并联电路和多串联电路。由于之前的输入信息中设备的引脚没有作用,所以我的正则表达式只用来提取设备的名字。而互斥开关有三个引脚,不同引脚的电压也不一样,所以这次......
  • Jiva语言学习报告(第一周)
    学习内容与进度:学习了Jiva的变量声明、数据类型(如整型、浮点型、字符串等)以及基本的运算符。掌握了条件语句(如if-else结构)和循环语句(如for循环、while循环)。实践项目:下载了Jiva语言编译环境完成了一个简单的计算器程序,实现了加、减、乘、除等基本运算。下周学习计划:了解如......
  • 2024.7 总结
    数据结构【CF380C】SerejaandBrackets题目描述本题中「合法括号串」的定义如下:空串是「合法括号串」。若\(s\)是「合法括号串」,则\((s)\)是「合法括号串」。若\(s,t\)是「合法括号串」,则\(st\)是「合法括号串」。有一个括号串\(s\)。\(m\)次操作。操作有......
  • conda 源设置方法总结
    conda源设置有2种方法。1是直接在命令行设置。2是使用配置文件.condarc中写入配置频道。命令行设置condaconfig--addchannelshttps://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/freecondaconfig--addchannelshttps://mirrors.tuna.tsinghua.edu.cn/anaconda/......