我的思路算法解释
假如节点一共只有四个
比如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算法
还是挺有收获的吧
要舍得多花时间 思考
这样对这些算法的思考程度才会更深!
希望能对大家有所帮助
快乐~