图的最短路径之Floyd算法C/C++代码实现_Traving Yu的博客-程序员宅基地

技术标签: 算法  数据结构与算法  数据结构  

弗洛伊德Floyd算法:

也称插点法,该算法用来求解每一对顶点之间的最短路径

假设从顶点1到2,顶点3为过度中间顶点则:
如果某个顶点位于从起点到终点的最短路径上:
1->2=(1->3)+(3->2)
如果某个顶点不在从起点到终点的最短路径上:
1->2<(1->3)+(3->2)

总结:从i号顶点到j号顶点只经过前k号点的最短路径
以该图为例:
在这里插入图片描述

辅助数组的变化过程:
在这里插入图片描述

代码如下:

#include<stdio.h>

#define MaxInt 999			//定义无穷大
#define MVNum 100
typedef char VerTexType;    //顶点类型
typedef int ArcType;		//边权值类型

//邻接矩阵存储结构
typedef struct
{
    
	VerTexType vexs[MVNum];				//顶点表
	ArcType arcs[MVNum][MVNum];			//邻接矩阵
	int vexnum, arcnum;					//图的当前点数和边数
}AMGraph;

void printGraph(AMGraph G);
int LocateVex(AMGraph G, char v);

//创建有向网
void CreateUDN(AMGraph &G)
{
    
	G.vexnum = 4;						//输入总顶点数和边数
	G.arcnum = 8;
	G.vexs[0] = 'v0';					//输入顶点信息
	G.vexs[1] = 'v1';
	G.vexs[2] = 'v2';
	G.vexs[3] = 'v3';

	for (int i = 0; i < G.vexnum; i++)			//初始化邻接矩阵为极大值
	{
    
		for (int j = 0; j < G.vexnum; j++)
		{
    
			G.arcs[i][j] = MaxInt;
		}
	}

	//输入权值
	int i, j;
	i = LocateVex(G, 'v0');
	j = LocateVex(G, 'v1');
	G.arcs[i][j] = 1;
	i = LocateVex(G, 'v0');
	j = LocateVex(G, 'v3');
	G.arcs[i][j] = 4;
	i = LocateVex(G, 'v1');
	j = LocateVex(G, 'v3');
	G.arcs[i][j] = 2;
	i = LocateVex(G, 'v1');
	j = LocateVex(G, 'v2');
	G.arcs[i][j] = 9;
	i = LocateVex(G, 'v2');
	j = LocateVex(G, 'v0');
	G.arcs[i][j] = 3;
	i = LocateVex(G, 'v2');
	j = LocateVex(G, 'v1');
	G.arcs[i][j] = 5;
	i = LocateVex(G, 'v2');
	j = LocateVex(G, 'v3');
	G.arcs[i][j] = 8;
	i = LocateVex(G, 'v3');
	j = LocateVex(G, 'v2');
	G.arcs[i][j] = 6;

	//自己到自己初始化为0
	i = LocateVex(G, 'v0');
	j = LocateVex(G, 'v0');
	G.arcs[i][j] = 0;
	i = LocateVex(G, 'v1');
	j = LocateVex(G, 'v1');
	G.arcs[i][j] = 0;
	i = LocateVex(G, 'v2');
	j = LocateVex(G, 'v2');
	G.arcs[i][j] = 0;
	i = LocateVex(G, 'v3');
	j = LocateVex(G, 'v3');
	G.arcs[i][j] = 0;
	

	printGraph(G);
}

//返回顶点在数组中的下标
int LocateVex(AMGraph G, char v)
{
    
	for (int i = 0; i < G.vexnum; i++)
	{
    
		if (G.vexs[i] == v)
		{
    
			return i;
		}
	}
}

//打印输出邻接矩阵
void printGraph(AMGraph G)
{
    
	for (int i = 0; i < G.vexnum; i++)
	{
    
		printf("v%d :", i + 1);

		for (int j = 0; j < G.vexnum; j++)
		{
    
			printf("%5d ", G.arcs[i][j]);
		}
		printf("\n");
	}
}

//邻接矩阵深度优先遍历
bool visited[MVNum];
void DFS_AM(AMGraph G, int v)
{
    
	printf("v%c->", G.vexs[v]);
	visited[v] = true;
	for (int w = 0; w < G.vexnum; w++)
	{
    
		if ((G.arcs[v][w]) != 0 && (!visited[w]))
		{
    
			DFS_AM(G, w);
		}
	}
}

//最短路径弗洛伊德算法
int D[MVNum][MVNum];			//存放v0到vi的最短路径长度值
int Path[MVNum][MVNum];			//存放vi的直接前驱顶点序号
void ShortestPath_Floyd(AMGraph G)
{
    
	//初始化
	for (int i = 0; i<G.vexnum; i++)
	{
    
		for (int j = 0; j<G.vexnum; j++)
			{
    
				D[i][j] = G.arcs[i][j];
				if (D[i][j] < MaxInt)		//i和j之间有弧
				{
    
					Path[i][j] = i;
				}
				else 
				{
    
					Path[i][j] =-1;
				}
			}
	}

	//算法开始
	for (int k = 0; k < G.vexnum; k++)			//过度顶点
	{
    
		for (int i = 0; i < G.vexnum; i++)		//起点
		{
    
			for (int j = 0; j < G.vexnum; j++)	//终点
			{
    
				if (D[i][k] + D[k][j] < D[i][j])		//如小于更新D[i][j]
				{
    
					D[i][j] = D[i][k] + D[k][j];
					Path[i][j] = Path[k][j];
				}
			}
		}
	}
	
}

//打印输出辅助数组D[i][j]和Path[i][j]
void printArray(AMGraph G)
{
    
	printf("\nD数组:\n");
	for (int i = 0; i < G.vexnum; i++)
	{
    
		printf("%d:", i);
		for (int j = 0; j < G.vexnum; j++)
		{
    
			printf("%5d", D[i][j]);
		}
		printf("\n");
	}

	printf("\nPath数组:\n");
	for (int i = 0; i < G.vexnum; i++)
	{
    
		printf("%d:", i);
		for (int j = 0; j < G.vexnum; j++)
		{
    
			printf("%5d", Path[i][j]);
		}
		printf("\n");
	}
}

int main()
{
    
	AMGraph G;
	CreateUDN(G);

	int v = 0;
	printf("深度优先遍历::");
	DFS_AM(G, v);

	int v0 = 0;
	printf("\n====================================\n");
	ShortestPath_Floyd(G);
	printArray(G);	//输出辅助数组D和Path
}

运行结果:

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_48268301/article/details/106884166

智能推荐

HDU 5054 Alice and Bob(数学)_aoe41606的博客-程序员宅基地

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5054Problem DescriptionBob and Alice got separated in the Square, they agreed that if they get separated, they'll meet back at...

关于11gR2RAC监听的跟踪排查_cipr45348的博客-程序员宅基地

现今客户对于数据库的安全越来越高,特别是网络安全这一部分,各种防火墙安全措施层出不穷,这就要就数据库DBA和网络工程师有一个很好的沟通,否则,沟通不够,往往存在着不小的麻烦,以下就是一次...

Hive的三种安装方式(内嵌模式,本地模式远程模式)_xfxf996的博客-程序员宅基地

本文转载自:https://www.cnblogs.com/tq03/p/5107949.html 作者:tq03 转载请注明该声明。一、安装模式介绍: Hive官网上介绍了Hive的3种安装方式,分别对应不同的应用场景。 1、内嵌模式(元数据保村在内嵌的derby种,允许一个会话链接,尝试多个会话链接时会报错) 2、本地模式(本地安装mysql 替代derby存储...

Android功耗-高通功耗问题分析(3)_StevenDuan17的博客-程序员宅基地

高通功耗问题分析高通官方提供了一篇文档extensive_power_debug_guide_(simplified_chinese功耗调试).pdf &nbsp;用来分析中断功耗问题。本文结合该文档简单的总结了AP端功耗问题分析手段。首先是官方功耗分析流程图:注意几个关键的名词:Modem&nbsp;调制解...

OpenGL ES之着色器语言的内建函数_会孵蛋的鱼的博客-程序员宅基地

角度转换与三角函数     getType radians(genType degrees)将角度转换为弧度 Result=(π/180)*degreesgetType degrees(genType radians)将弧度转化为角度 result=(180/π)*radiansgenType sin(genT

Maven:Missing artifact javax.servlet.jsp.jstl:jstl:jar:1.2 l_不朽的机器的博客-程序员宅基地

Maven pom.xml 中导入jstl依赖     &amp;lt;dependency&amp;gt; &amp;lt;groupId&amp;gt;javax.servlet.jsp.jstl&amp;lt;/groupId&amp;gt; &amp;lt;artifactId&amp;gt;jstl&amp;lt;/artifactId&amp;gt; &amp;lt;version&amp;gt;1.2&amp;lt;/version&amp;gt;&amp;

随便推点

三、Centos 7.6编译安装PHP7.3.10_江山灬如画的博客-程序员宅基地

3.编译安装PHP7.3安装PHP7.3是最曲折的,一开始采用源安装,先是缺少libphp7.so,与apache无法交互。然后搞定这个问题后运行wordpress又是提示Your PHP installation appears to be missing the MySQL extension which is required by WordPress.,原因是没有mysqli模块,与m...

tomato php mysql_Tomato手动零开始搭建nginx+php+mysql服务器教程(需要外置磁盘)_二枫居士的博客-程序员宅基地

1、格式化U盘成EX3格式。umount /dev/sda1umount /optmkfs.ext3 /dev/sda12、挂载opt分区(tmp/mnt/sda1是我的硬盘路径)在U盘上新建一个opt文件夹: mkdir tmp/mnt/sda1/opt挂载U盘到opt目录: mount -o bind /tmp/mnt/sda1/opt /opt3、安装optwarecd /optwgetht...

flask-admin 快速打造博客 系列二 (整合flask-admin)_weixin_34192732的博客-程序员宅基地

整合flask-admin前言Flask-admin 相当django的xadmin吧!可是xadmin虽然样式很漂亮,功能也很强大,可是灵活性不够,官方文档缺失,这两个原因就足以让我选择不用了。Flask-admin也是有使用局限性的,他只适合开发小型快速的应用,不适合那种大型并发性高,逻辑复杂的应用。首先,对于大型应用都是前后端...

一个可以爬取小说的小爬虫 - 来自业余编程人的第一篇编程分享_m.biqugei.info_三十未立的博客-程序员宅基地

内容提要最近闲来无事,网上找了本小说,翻来覆去的终于找到一个还不错的小说,然而所下载的小说质量实在不讨喜,错误重复随处可见,网站广告也夹杂其中,遂产生了自己爬小说的念头。还好小说的网站都比较简单,基本没有什么反爬措施。期间遇到一个神奇的网站,小说内容是用JS格式化加载的。后来想了一个办法,遇到加载未完成,重新请求即可。废话少说,我们来看代码。代码使用Python写的。麻雀虽小,五脏俱全整个...

研究使用FastJson把Java对象转JsonObject的效率问题,以及改进方案。_fastjson效率低_十年饮水不凉热血的博客-程序员宅基地

构造了一个稍微复杂的Java对象对比在不同情况下的转换效率,都是循环20次执行。https://gitee.com/icefire11/test-fast-json概述:Main方法示例:import com.alibaba.fastjson.JSONObject;public class Test { public static void main(String[] args) { School school = new School(); lon

Rancher在IPTABLES的应用_chuochuanqiang5408的博客-程序员宅基地

IPTABLES对运维的同学来说是一个非常有用的工具,配合tcpdump/wireshark来定位四层的收发包问题会格外的有效。比方说报文到了协议栈的设备上,通过tcpdump模拟协议栈抓到了交互的报文,但是报文没有往上投递到四层应用,这中间一定是有一些机制和策略阻碍的报文的向上投递,这时候在...

推荐文章

热门文章

相关标签