最小生成树和最短路径及其他

news2025/1/11 18:33:21

还是学过的,主要用于复习q v q

一、最小生成树

最小生成树的定义

用于无向图中,无向图指的是没有带方向路径的图,给定n个点,m条边,如果将这些点依次相连,求出连接这些点的最小数值

应用场景

根据这个算法特性,我们不能猜出此算法主要运用于要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。

prim算法

 此算法主要是通过选点来进行操作的

 例如此图,用一维数组a来存点,二维数组b来存路径,若从 1 点开始

a[ 2 ] = 2  a[ 3 ] = 4  a[ 4 ] = 7;

选择最小的边的点,就是点 2,那么将 1 ,2 的能连接的边关系为

a[ 3 ] = 1(因为 1 到 3 的路径太长,因此 3 的路径改为 1 )

a[ 5 ] = 2

选择最小边的点,就是点 3,那么将 1 ,2,3 的能连接的边关系为

a[ 4 ] = 1(因为 1 到 4 的路径太长,因此 4 的路径改为 1 )

a[ 5 ] = 2(不变)

因此最终为

 

核心代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;

#define INF 0x3f3f3f3f  //超大数

int N;  //  储存图
int map[105][105];   //	顶点有没有被访问
bool book[105];     //	存储大圈圈
int lenth[105];
int Prime() 
{
	memset(book, false, sizeof(book));  //初始化
	int sum = 0;
	book[0] = true;

    //    选中了0这个点,0到n个点的边权

	for (int i = 1 ; i < N ; i++) {
		lenth[i] = map[0][i];
	}

	for (int i = 1 ; i < N ; i++) 
    {
		int min = INF;
		int node;
		for (int j = 1 ; j < N ; j++) 
        {
			if (book[j] == false && lenth[j] < min) 
            {

                //记录最小的边权值

				min = lenth[j];

                //记住这个最小的边的下标

				node = j;
			}
		}

        //得到大圈圈中的最小边,讲其加入到最小边边

		sum += min;

        //更新到了的顶点

		book[node] = true;
		for (int i = 1 ; i < N ; i++) 
        {
			if (book[i] == false && lenth[i] > map[node][i]) {
				lenth[i] = map[node][i];
			}
		}
		cout << i;
	}
	return sum;  //返回最短边权和
}

int main() 
{
	while (cin >> N) 
    {
		for (int i = 0 ; i < N ; i++) 
        {
			for (int j = 0 ; j < N ; j++) {
				scanf("%d", &map[i][j]);    //输入邻接矩阵
			}
		}
		cout << Prime() << endl;
	}

	return 0;
}

kruskal算法

kruskal算法也没啥好说的了,也就是将边权排序,依次选最小的边,当选的边等于点的数量 - 1的时候就结束,但是在这过程要注意不要围成圈了,因此就需要并查集解决这个问题,那么直接上代码吧

代码模板

#include <bits/stdc++.h>
using namespace std;
int n, m, v, k, ans, fa[10000001];

struct node    //定义结构体存图 
{
    int x;
    int y;
    int z;    //z表示x连y的权值 
}stu[100001];

//并查集 

int find(int x)
{
    if (x != fa[x]){
        fa[x] = find(fa[x]);
    }
    return fa[x];
}//查找 

void unity(int x, int y)
{
    int r1 = find(x);
    int r2 = find(y);
    fa[r1] = r2;
}//合并

bool cmp(node a, node b)    //从小到大结构体排序 
{
    return a.z < b.z;
}

int main()
{
    scanf("%d", &n);

    for (int i = 1; i <= n; i++){       //并查集初始化
        fa[i] = i;       
    }

    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            scanf("%d", &v);
            if (j > i)          //邻接矩阵上下对称,存一半就行了 
            {
                m++;
                stu[m].x = i;
                stu[m].y = j;
                stu[m].z = v;
            }
        }
    }

    sort(stu + 1, stu + m + 1, cmp);    //排序 

    for (int i = 1; i <= m; i++)
    {
        if (find(stu[i].x) != find(stu[i].y))  //不能连自己
        {
            ans += stu[i].z;//加上最小生成树中边的权值 
            unity(stu[i].x, stu[i].y);//连接起来 
            k++;//记录边数 
            if (k == n - 1)//n - 1条边就行了 
            {
                printf("%d", ans);
                return 0;
            }
        }
    }
    return 0;
}

二、最短路径

最短路径的定义

最短路径一般用于有相同,就是带有方向的路径图

在一个图中,会出现这样的问题,要求你求出一个点到各个点的最短的路径,而这时你可能会想,那这个是不是跟那个最小生成树是不是就是一样的呢?其实不然,最小生成树是连接各个点形成的最小路径,而最短路径则是俩个点之间的最短路径,是不相同的。

迪杰斯特拉算法(dijkstra)

基本思想

首先假定源点为u,顶点集合V被划分为两部分:集合 S 和 V-S。    初始时S中仅含有源点u,其中S中的顶点到源点的最短路径已经确定。
集合S 和V-S中所包含的顶点到源点的最短路径的长度待定,称从源点出发只经过S中的点到达V-S中的点的路径为特殊路径,
并用dist[]记录当前每个顶点对应的最短特殊路径长度。

那么具体的图解我感觉在http://t.csdn.cn/HV7ku

这里面已经写的够清楚了,所以这次就偷个懒,再附赠一张大佬的动态图吧

在这里插入图片描述

 代码模板

#include<stdio.h>
#include<iostream>

using namespace std;
#define SIZE 110
#define INF 1000000  //相当于无穷大,判断点与点的连接时需要
int map[SIZE][SIZE];  //邻接矩阵存储
int dis[SIZE];  	//d[i]表示源点到i这个点的距离
int visit[SIZE];  //节点是否被访问
int n, m, j, pos, ans, temp = INF;

int dijkstra(int from, int to)   //从源点到目标点
{	
	int i;
	for (i = 1; i <= n; i++)  //初始化
	{	
		visit[i] = 0;	//一开始每个点都没被访问
		dis[i] = map[from][i];	//先假设源点到其他点的距离
	}

	for (i = 1; i < n; ++i)	  //对除源点的每一个点进行最短计算
	{				
		int min = INF;		//记录最小len[i]

		//记录小len[i] 的点
		for (j = 1; j <= n; ++j) {
			if (!visit[j] && min > dis[j]) {
				pos = j;
				min = dis[j];
			}
		}
		visit[pos] = 1;
		for (j = 1; j <= n; ++j) 
		{
			//如果j节点没有被访问过&&j节点到源节点的最短路径>pos节点到源节点的最短路径+pos节点到j节点的路径
			if (!visit[j] && (dis[j] > (dis[pos] + map[pos][j]))) { 
				dis[j] = dis[pos] + map[pos][j];	//更新j节点到源节点的最短路径
			}
		}
	}
	return dis[to];
}

int main() {

	int i, j;

	//  scanf("%d%d",&n,&m);	//输入数据

	//测试数据
	n = 6;	
	m = 9;

	for (i = 1; i <= n; ++i) {		//设一开始每个点都不可达
		for (j = 1; j <= n; ++j) {
			map[i][j] = INF;
		}
	}

	/*	int a,b,c;	//输入数据
		for(i = 1 ; i <= m ; ++i){
			scanf("%d%d%d",&a,&b,&c);
			map[a][b] = map[b][a] = c;
		}  */

	//测试数据
	map[1][2] = 7;	
	map[1][3] = 9;
	map[1][6] = 14;
	map[2][3] = 10;
	map[2][4] = 15;
	map[3][6] = 2;
	map[5][6] = 9;
	map[4][5] = 6;
	map[3][4] = 11;

	/*	这里的一步完全不用的,多此一举而已,是判断双向边的
		for (i = 1 ; i <= n ; ++i) {
			for (j = 1 ; j <= n ; ++j) {
				if (map[i][j] == temp)
					map[i][j] = map[j][i];
			}
		}*/

	printf("%d", ans = dijkstra(2, 5));

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416497.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

9 个JSON.stringify的秘密大多数开发人员却不知道

作为前端开发工程师&#xff0c;你一定用过JSON.stringify&#xff0c;但你知道它的全部秘密吗&#xff1f; 很久以前&#xff0c;我因此在工作中犯下了无法挽回的错误。如果我早点知道&#xff0c;就不会发生这样的悲剧。 理解 JSON.stringify 基本上&#xff0c;JSON.stri…

神经网络辐射场NeRF、实时NeRF Baking、有向距离场SDF、占用网络Occupancy、NeRF 自动驾驶

1 NeRF原理2 NeRF加速PlenoxelsKiloNeRFInstant NGPTensoRF3 SDF NeRF4 Occupancy NeRF5 NeRF应用简介常见应用实际应用的挑战6 NeRF自动驾驶1 NeRF原理 NeRF (Neural Radiance Fields&#xff0c;神经辐射场) 是2020年ECCV会议上的Best Paper&#xff0c;其将隐式表达推上了…

安卓玩机搞机----移植第三方rom修复 第三方GSI系统修复bug综合解析【一】

很多朋友热衷与刷写第三方非当前机型官方系统的rom。和刷写第三方gsi等等。例如 米系列机型刷写Flyme 一加机型刷写miui oppo刷写gsi等等。 很多友友也会尝试自己移植第三方rom。但此类操作最大的问题在于修复可以开机后的bug&#xff0c;今天的教程综合说明下这类修复思路…

STM32F103RCT6

STM32F103RCT6是一款由STMicroelectronics公司生产的基于ARM Cortex-M3内核的32位微控制器。 它具有高性能、低功耗和广泛的应用领域。 包括ADC&#xff08;模数转换器&#xff09; DAC&#xff08;数字模拟转换器&#xff09; TIM&#xff08;定时器&#xff09; USART&#x…

Python 中 SyntaxError: ‘yield‘ outside function 错误

当我们在函数外部使用 yield 关键字时&#xff0c;会出现 Python “SyntaxError: ‘yield’ outside function”。 要解决该错误&#xff0c;如果我们需要对每个元素执行一些运算符&#xff0c;请使用列表理解&#xff0c;或者缩进函数内部使用 yield 的代码。 下面是一个产生…

Maven(四):Maven的使用(中)

Maven&#xff08;四&#xff09;&#xff1a;Maven的使用&#xff08;中&#xff09;前言一、实验四&#xff1a;创建 Maven 版的 Web 工程1、说明2、操作3、生成的pom.xml4、生成的Web工程的目录结构5、创建 Servlet5.1 在 main 目录下创建 java 目录5.2 在 java 目录下创建 …

【从零开始学Skynet】实战篇《球球大作战》(六):gateway代码设计(中)

1、编码和解码 我们来实现两个辅助方法str_unpack和str_pack&#xff0c;用于消息的解码和编码。 &#xff08;1&#xff09;str_unpack代码 local str_unpack function(msgstr)local msg {}while true dolocal arg, rest string.match( msgstr, "(.-),(.*)")if…

TCP/IP协议及配置

文章目录一、TCP/IP概述1. TCP/IP协议族2. 主机与主机之间通信的三个要素二、什么是IP地址1. 用来标识一个网络节点的互联网地址&#xff08;如同电话的号码&#xff09;2. IPv4地址组成三、IP地址分类1. 常用的IP地址2. 组播及科研专用四、IP地址分类&#xff08;续&#xff0…

wsl下安装cuda各种踩坑记录.assets

执行nvcc -V, cuda版本位11.5 删除cuda sudo apt-get --purge remove "*cublas*" "*cufft*" "*curand*" \"*cusolver*" "*cusparse*" "*npp*" "*nvjpeg*" "cuda*" "nsight*"选择对…

打造自己特色远程桌面:SmartCode ViewerX Crack

SmartCode ViewerX VNC 查看器 ActiveX 毫不费力地将 VNC 查看器功能添加到您的应用程序 SmartCode ViewerX VNC 查看器 ActiveX 使开发人员可以使用一组直观的 ActiveX 属性和方法完全访问 VNC 查看器功能。借助ViewerX 控件&#xff0c;开发人员可以轻松地为其应用程序提供…

<呕心沥血>一文总结数据结构八大排序(持续更新)

目录 一、常见的八大排序 二、八大排序的算法思想 1、冒泡排序 2、选择排序 3、插入排序 4、希尔排序 5、归并排序 6、快速排序 7、堆排序 8、计数排序 三、八大排序的算法实现 一、常见的八大排序 常见的八大排序算法如下&#xff1a; 冒泡排序&#xff08;Bubble …

Android中的接口回调机制

文章目录1.回调的含义和用途2.java实现接口回调3.Android中接口回调的体现4.接口回调在异步任务中的体现1.回调的含义和用途 一般来说&#xff0c;模块之间都存在一定的调用关系&#xff0c;从调用方式上看&#xff0c;可以分为三类同步调用、异步调用和回调。同步调用是一种阻…

JAVAWeb04-DOM

1. DOM 1.1 概述 1.1.1 官方文档 地址: https://www.w3school.com.cn/js/js_htmldom.asp 1.1.2 DOM 介绍 DOM 全称是 Document Object Model 文档对象模型就是把文档中的标签&#xff0c;属性&#xff0c;文本&#xff0c;转换成为对象来管理 1.2 HTML DOM&#xff08;文档…

为什么现代企业都在使用ERP系统 它有哪些优势

随着科技的不断发展&#xff0c;企业管理方式也在不断地发生改变。在这个信息化的时代&#xff0c;企业要想取得成功&#xff0c;必须要善于利用先进的信息化技术工具。其中&#xff0c;ERP系统是企业管理中不可或缺的重要工具。本文将探讨现代企业为什么会使用ERP系统&#xf…

CPU占用率高怎么办?正确解决方法在这里!

案例&#xff1a;CPU占用率高怎么解决 【各位朋友&#xff0c;我的电脑现在运行太慢了&#xff0c;同事说可能是CPU占用率太高了&#xff0c;但对本电脑小白来说&#xff0c;完全不知道怎么处理&#xff0c;大家有什么好的方法可以解决这个问题吗&#xff1f;】 在计算机中&a…

快看这些wireshark 命令,必须得会!

wireshark捕获命令 捕获器表达式语法&#xff1a; 限定词三类 Type&#xff1a;host、net、prot 指出其后数字或名字的意义&#xff08;主机&#xff0c;网段&#xff0c;端口&#xff09; Direction&#xff1a;src、dst 指出传输方向 &#xff08;源 、目的&#xff09; …

GcExcel Java Edition 6.0.6 Crack

概述 GrapeCity Documents for Excel&#xff0c;Java 版&#xff0c;是一个编程接口&#xff0c;允许 Java 开发人员以编程方式大规模创建和操作 Excel 文档。GrapeCity Documents for Excel 是一种解决方案&#xff0c;允许开发人员跨 Java 应用程序导入/导出、创建报告和模板…

论文阅读《GlueStick: Robust Image Matching by Sticking Points and Lines Together》

论文地址&#xff1a;https://arxiv.org/abs/2304.02008 源码地址&#xff1a;https://github.com/cvg/GlueStick 概述 针对视角变化时在闭塞、无纹理、重复纹理区域的线段匹配难的问题&#xff0c;本文提出一种新的匹配范式&#xff08;GlueStick&#xff09;&#xff0c;该方…

MySQL性能优化(三)事务与锁详解

文章目录什么是数据库事务&#xff1f;事务的四大特性&#xff1a;ACID事务的开启与结束案例表结构与数据案例事务并发的三大问题&#xff1a;脏读&#xff08;一个事务读取到了其他事务未提交的数据&#xff09;不可重复读&#xff08;一个事务读取到其他事务已提交的数据造成…

Qt在安卓手机输出‘hello,world‘

我也想实现这样的功能。 最开始的参考文章&#xff1a; (2条消息) Qt android 开发环境搭建_逝水流年丶轻染尘的博客-CSDN博客 方案1&#xff1a;(失败) 我之前已经下载过 Qt5.14.2了&#xff0c;所以我想直接添加组件 中间过程参考&#xff1a; (2条消息) Qt更新组件出现&…