(c语言)Floyd算法总结(多源最短路径)

我的思路算法解释

假如节点一共只有四个
比如3直接到4的话
假设3->4路程为10

如果需要变短一段路径
我们可以比较
假设
3->1 1->4之和(1)路程为8
3->2 2->4之和(2)路程为12
3->3 3->4之和(3)路程为10
3->4 4->4之和(4)路程为10
去与原来的直接相连进行比较
所以我们不难发现
第一
每次我们变短时我们都利用了一个节点
比如(1)中 我们就利用了中转点 1号节点
(2)我们就利用了中转点 2号节点

那我们是不是可以得出
任何两个直接相连一段距离 如果可以变短
我们都可以利用中转点把它变短

那推理到一段距离 也许是需要很多个中转点才是最近距离
那我们可以把这段距离切分为很多很小的距离
很多很小的距离再进行切分 直到一段距离
一个中转点就把他们变短了
然后这段很长的距离就是 很多段被切分的距离的总集

那如果我们对任意两段距离
对我们每个节点都进行尝试 能不能变短
那是不是每一小段距离都是最短的



啊哈算法思路解释(思路十分简单清晰)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述




代码实现

#include <stdio.h>
#define MAX 11
#define inf 9999999

int G[MAX][MAX];
int Nv,Ne;
void InitGraph();
void InsertWeight();
void Floyd();
void Print();

//初始化图
void InitGraph()
{
    int i,j;
    for(i=1;i<=Nv;i++)
        for(j=1;j<=Nv;j++)
            G[i][j] = inf;

    for(i=1;i<=Nv;i++)
        G[i][i] = 0;
    return;
}

//插入权值
void InsertWeight()
{
    int InitVer,DesVer,weight,i;
    for(i=1;i<=Ne;i++)
    {
        scanf("%d %d %d",&InitVer,&DesVer,&weight);
        G[InitVer][DesVer] = weight;
    }
    return;
}

//Floyd算法
void Floyd()
{
    int i,j,k;

	//k表示每个节点
    for(k=1;k<=Nv;k++)
    {
        for(i=1;i<=Nv;i++)
        {
            for(j=1;j<=Nv;j++)
            {
                if(G[i][j] > G[i][k] + G[k][j])
                    G[i][j] = G[i][k] + G[k][j];
            }
        }
    }
    return;
}

//输出函数
void Print()
{
    int i,j;
    for(i=1;i<=Nv;i++)
    {
       for(j=1;j<=Nv;j++)
        {
            if(G[i][j]!=inf)
                printf("%d ",G[i][j]);
        }
        if(i!=Nv)
        printf("\n");
    }
    return;
}

//主函数
int main()
{
    scanf("%d %d",&Nv,&Ne);
    InitGraph();
    InsertWeight();
    Floyd();
    Print();
    return 0;
}


测试数据

INPUT:
4 8
1 2 2
1 3 6
1 4 4
2 3 3
3 1 7
3 4 1
4 1 5
4 3 12


OUTPUT:
0 2 5 4
9 0 3 4
6 8 0 1
5 7 10 0



结束语

这就是全部的总结了
今天一个下午还算是大概搞懂了Floyd算法和Dijkstra算法
还是挺有收获的吧
要舍得多花时间 思考
这样对这些算法的思考程度才会更深!
希望能对大家有所帮助

快乐~
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love 6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值