图论——最短路算法

 引入:

如上图,已知图G。

问节点1到节点3的最短距离。

可心算而出为d[1,2]+d[2,3]=1+1=2,比d[1,3]要小。

求最短路径算法:

1.Floyd(弗洛伊德)

是一种基于三角形不等式的多源最短路径算法。边权可以为负数

表现为a[i,j]+a[j,k]<a[i,k]。

算法思想:

枚举“中转站”(k),“起点”(i),“终点”(j)

设d[i,j]为由i点到j点的最短路径

则 d[i,j]=min(d[i,j],d[i,k]+d[k,j])

初始化d[i,j]为无穷大 (1\leq i\leq n,1\leq j\leq n

算法模板如下:
 

inline int Floyd(int n,int st,int ed)// n个点,起点st,终点ed,返回st到ed的最短距离
{
    int d[n][n];
    memset(d,0x3f,sizeof(d));
    for(int i=1;i<=n;i++) d[i][i]=0;
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
            }
        }
    }
    return d[st][ed];
}

 补充:Floyd输出最短路径。

题目:有向图中任意两点最短路径(floyd)

题目描述

  一个含n个结点的有向图(注意:是有向图!!),以矩阵存储方式给出,请求出指定的多组两个点之间的最短距离及其最短路径。

输入输出格式
输入格式:

  第1行,一个整数n(0 < n < 300 ),表示有向图中结点的个数。
  第2行到第(n+1)行,是一个n*n的矩阵,表示无向图中各结点之间的联结情况,矩阵中的数据为小于1000的正整数,其中 -1 表示无穷大!!
  第(n+2)行,一个整数m,表示接下来有m组顶点 < i , j >对 ,其中,i是起点,j是终点,且i不等于j。
  接下来有m行,每行两个整数,中间一个空格间隔,分别表示i和j,表示求解i点到j点的最短距离及最短路径。

  注:输入数据已经确保答案每一组顶点间的最短路径是唯一的,无多解数据存在,顶点编号用数字表示,从1开始编号,至n结束!

输出格式:

  共 2m 行。
  第(m-1)*2+1行,一个整数,表示第m组顶点的最短距离,若两点间距离为无穷大,则输出 -1。
  第(m-1)*2+2行,用顶点编号表示的路径序列,各顶点编号间用一个空格间隔,表示第m组顶点的最短路径,若两点间距离为无穷大,则输出的路径序列为 -1。

输入输出样例
输入样例#1:

3
0 4 11
6 0 2
3 -1 0
2
2 1
3 2 

输出样例#1:

5
2 3 1
7
3 1 2

代码如下:
 

#include<bits/stdc++.h>
using namespace std;
int n,q;
int d[10001][10001],pre[10001][10001];
void dg(int i,int j)
{
	if(i==j||pre[i][j]==0) return;
	int k=pre[i][j];
	dg(i,k);
	dg(k,j);
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>d[i][j];
			if(d[i][j]==-1)
			{
				d[i][j]=0x7fffff;
			}
		}
	}
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(d[i][k]+d[k][j]<d[i][j])
				{
					d[i][j]=d[i][k]+d[k][j];
					pre[i][j]=k;
				}
			}
		}
	}
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		int x,y;
		cin>>x>>y;
		cout<<d[x][y]<<endl;
		cout<<x<<" ";
		dg(x,y);
		cout<<y;
		cout<<endl;
	}
	return 0;
}

传递闭包(连通性)

d[i,j]=d[i,j]|(d[i,k]&d[k,j])
d[i,j]表示i与j是否连通。

题目:刻录光盘

题目描述

  在FJOI2010夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘给大家,以便大家回去后继续学习。组委会觉得这个主意不错!可是组委会一时没有足够的空光盘,没法保证每个人都能拿到刻录上资料的光盘,怎么办呢?!

  DYJ分析了一下所有营员的地域关系,发现有些营员是一个城市的,其实他们只需要一张就可以了,因为一个人拿到光盘后,其他人可以带着U盘之类的东西去拷贝啊!

  他们愿意某一些人到他那儿拷贝资料,当然也可能不愿意让另外一些人到他那儿拷贝资料,这与我们FJOI宣扬的团队合作精神格格不入!!!

  现在假设总共有N个营员(2<=N<=200),每个营员的编号为1~N。DYJ给每个人发了一张调查表,让每个营员填上自己愿意让哪些人到他那儿拷贝资料。当然,如果A愿意把资料拷贝给B,而B又愿意把资料拷贝给C,则一旦A获得了资料,则B,C都会获得资料。

  现在,请你编写一个程序,根据回收上来的调查表,帮助DYJ计算出组委会至少要刻录多少张光盘,才能保证所有营员回去后都能得到夏令营资料?

输入输出格式

输入格式:

先是一个数N,接下来的N行,分别表示各个营员愿意把自己获得的资料拷贝给其他哪些营员。即输入数据的第i+1行表示第i个营员愿意把资料拷贝给那些营员的编号,以一个0结束。如果一个营员不愿意拷贝资料给任何人,则相应的行只有1个0,一行中的若干数之间用一个空格隔开。

输出格式:

一个正整数,表示最少要刻录的光盘数。

输入输出样例

输入样例#1:

5
2 4 3 0
4 5 0
0
0
1 0

输出样例#1:

1

代码:

#include<bits/stdc++.h>
using namespace std;
int f[100001],d[300][300],g[100001],ans;
int main()
{
	int n;
	cin>>n;
	memset(d,0x3f,sizeof(d));
	for(int i=1;i<=n;i++)
	{
		f[i]=i;
	}
	for(int i=1;i<=n;i++)
	{
		int x;
		while(1)
		{
			cin>>x;
			if(x==0) break;
			d[i][x]=1;
		}
	}
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i!=j&&j!=k&&k!=i)
				{
					if(d[i][k]==1&&d[k][j]==1)
					{
						d[i][j]=1;
					}
				}
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(d[i][j]==1)
			{
				f[j]=f[i];
			}
		}
	}
	for(int i=1;i<=n;i++) 
	{
		if(f[i]==i) 
		{
			ans++;
		}
	}
	cout<<ans;
	return 0;
} 

2.dijkstra(狄克斯特拉,迪杰斯特拉)

基于贪心的单源最短路径算法。边权必须为正数

基本思想:

设d[i]为起点s到终点i的最短路径,a[i,j]为点i到点j边权。

1.找  min\begin{Bmatrix} d[i] \end{Bmatrix}\left ( 1\leqslant i\leqslant n ,vis[i]=true \right ),并将其用k记录

2.vis[k]=true

3.d[i]=min\begin{Bmatrix} d[i],d[k]+a[k][i] \end{Bmatrix}\left ( 1\leqslant i\leqslant n \right ) 松弛操作,用k来更新图中所有点。

int dijkstra(int n,int st,int ed)
{
    int dis[n+1],vis[n+1];
    memset(dis,0x3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    dis[st]=0;
    for(int i=1;i<=n;i++)
    {
        int k,minn=0x7fffff;
        for(int j=1;j<=n;j++)if(!vis[j]&&dis[j]<minn) minn=dis[j],k=j;
        vis[k]=true;
        for(int j=1;j<=n;j++) d[j]=min(d[j],d[k]+a[k][j]);
    }
    return d[ed];
}

堆优化dijkstra:
 

typedef pair<int,int> P;
struct node{
	int to;
	int next;
	int w;
}edge[10000010];
int head[10000010],d[10000010];
int cnt;
int n,m,x,y,z,s;
void add_edge(int u,int v,int w)
{
	edge[cnt].to=v;
	edge[cnt].w=w;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}
void dijkstra(int s)
{
	priority_queue< P,vector<P>,greater<P> >q;
	memset(d,0x3f,sizeof(d));
	d[s]=0;
	q.push(P(0,s));
	while(!q.empty())
	{
		P p=q.top();
		q.pop();
		int u=p.second;
		if(d[u]<p.first) continue;
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].to;
			if(d[v]>d[u]+edge[i].w)
			{
				d[v]=d[u]+edge[i].w;
				q.push(P(d[v],v));
			}
		}
	}
}

3.Bellman-Ford

O(n*m) 但有更优的,由其转换而来的Spfa算法,不再赘述。边权可以为负数

4.Spfa

基于bellman-Ford,用队列优化的单源最短路径算法,边权可以为负数,可用于判断负环。

代码如下:

    int head=0,tail=1;
	team[1]=s,vis[s]=1,dis[s]=0;
	while(head<tail)
	{
		head=(head+1)%10000;
		int u=team[head];
		vis[u]=0;
		for(int i=1;i<=len[u];i++)
		{
			int v=le[u][i];
			if(dis[v]>dis[u]+a[u][v])
			{
				dis[v]=dis[u]+a[u][v];
				if(vis[v]==0)
				{
					tail=(tail+1)%10000;
					team[tail]=v;
					vis[v]=1;
				}
			}
		}
	}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

9.2.2Socket(TCP)

一.过程: 1.建立连接(不是握手),虽然内核中的连接有很多,但是在应用程序中,要一个一个处理. 2. 获取任务:使用ServerSocket.accept()方法,作用是把内核中的连接获取到应用程序中,这个过程类似于生产者消费者模型. 3. 使用缓冲的时候,注意全缓冲和行缓冲. 4.注意关闭文件资源…

排序算法(二)

1.希尔排序-Shell Sort 1.算法原理 将未排序序列按照增量gap的不同分割为若干个子序列&#xff0c;然后分别进行插入排序&#xff0c;得到若干组排好序的序列&#xff1b; 缩小增量gap&#xff0c;并对分割为的子序列进行插入排序&#xff1b;最后一次的gap1&#xff0c;即整个…

SQL 基础查询

msyql 不区分大小写 DDL 数据定义语言 查询 show databases create database db01 创建数据库 create database if not exists db01 创建数据库 删除数据库 drop database if exists db01 使用数据库 use 数据库名 CREATE TABLE tb_user(id int PRIMARY KEY COMMENT i…

简单易用且高效的跨平台开发工具:Xojo 2023 for Mac

Xojo for Mac是Mac平台上一个跨平台的针对桌面、Web、移动和Raspberry Pi的快速应用程序开发软件。与其他多平台开发工具相比&#xff0c;Xojo for Mac为开发人员提供了显着的生产率提高。 Xojo for Mac具有拖放功能&#xff0c;使您能够快速创建用户界面设计&#xff0c;然后…

【Linux初阶】进程间通信介绍 管道

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【Linux初阶】 ✒️✒️本篇内容&#xff1a;进程间通信介绍&#xff0c;管道概述&#xff0c;匿名管道应用&#xff0c;命名管道应用 &#x1f6a2;&#…

如何在 Spring Boot 中集成日志框架 SLF4J、Log4j

文章目录 具体步骤附录 笔者的操作环境&#xff1a; Spring Cloud Alibaba&#xff1a;2022.0.0.0-RC2 Spring Cloud&#xff1a;2022.0.0 Spring Boot&#xff1a;3.0.2 Nacos 2.2.3 Maven 3.8.3 JDK 17.0.7 IntelliJ IDEA 2022.3.1 (Ultimate Edition) 具体步骤 因为 …

HTTP代理编程:Python实用技巧与代码实例

今天我要与大家分享一些关于HTTP代理编程的实用技巧和Python代码实例。作为一名HTTP代理产品供应商&#xff0c;希望通过这篇文章&#xff0c;帮助你们掌握一些高效且实用的编程技巧&#xff0c;提高开发和使用HTTP代理产品的能力。 一、使用Python的requests库发送HTTP请求&a…

【ElasticSearch入门】

目录 1.ElasticSearch的简介 2.用数据库实现搜素的功能 3.ES的核心概念 3.1 NRT(Near Realtime)近实时 3.2 cluster集群&#xff0c;ES是一个分布式的系统 3.3 Node节点&#xff0c;就是集群中的一台服务器 3.4 index 索引&#xff08;索引库&#xff09; 3.5 type类型 3.6 doc…

STM32F429IGT6使用CubeMX配置串口通信

1、硬件电路 2、设置RCC&#xff0c;选择高速外部时钟HSE,时钟设置为180MHz 3、配置USART1引脚 4、生成工程配置 5、部分代码 //重定向printf函数 int fputc(int ch, FILE *f) {HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);return ch; } /* USER CODE BE…

Mac M1 安装Oracle Java 与 IEDA

文章目录 1 官网下载2 安装IDEA参考 1 官网下载 https://www.oracle.com/ 使用finder中的拖拽进行安装即可 2 安装IDEA https://www.jetbrains.com/zh-cn/idea/download/?sectionmac 同样的&#xff0c;下载完后拖拽安装即可 参考 Mac M1 安装Java 开发环境 https://blog.…

cuda+anaconda+pytorch按照教程

首先安装显卡对应的CUDA版本&#xff0c;关键点在于区别显卡支持的CUDA最高版本和运行版本 1、查看当前显卡支持的最高版本&#xff0c;有两种方式&#xff1a; 1&#xff09;NVIDIA控制面板—>帮助—>系统信息—>组件—>NVCUDA.dll对应版本 请注意&#xff0c;12…

快速上手React:从概述到组件与事件处理

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

React源码解析18(1)------ React.createElement 和 jsx

1.React.createElement 我们知道在React17版本之前&#xff0c;我们在项目中是一定需要引入react的。 import React from “react” 即便我们有时候没有使用到React&#xff0c;也需要引入。原因是什么呢&#xff1f; 在React项目中&#xff0c;如果我们使用了模板语法JSX&am…

Spring-1-深入理解Spring XML中的依赖注入(DI):简化Java应用程序开发

学习目标 前两篇文章我们介绍了什么是Spring,以及Spring的一些核心概念&#xff0c;并且快速快发一个Spring项目&#xff0c;以及详细讲解IOC&#xff0c;今天详细介绍一些DI(依赖注入) 能够配置setter方式注入属性值 能够配置构造方式注入属性值 能够理解什么是自动装配 一、…

【C语言】每日一题---1

大家好&#xff0c;我是苏貝&#xff0c;本篇博客是系列博客每日一题的第一篇&#xff0c;本系列的题都不会太难&#xff0c;如果大家对这种系列的博客感兴趣的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 下面代码的结果是&#xff1a; #include <…

【Nginx】Nginx负载均衡

负载均衡&#xff1a;通过反向代理来实现 Nginx的七层代理和四层代理&#xff1a; 七层是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块当中 &#xff1b;配置的方法名称为&#xff1a;upstream模块&#xff0c;不能写在server中也不能写在location中&a…

爬虫ip池越大越好吗?

作为一名资深的程序员&#xff0c;今天我要给大家分享一些关于爬虫ip池的知识。关于ip代理池的问题&#xff0c;答案是肯定的&#xff0c;池子越大越好。下面跟我一起来盘点一下ip池大的好处吧&#xff01; 1、提高稳定性 爬虫ip池越大&#xff0c;意味着拥有更多可用的爬虫ip…

大O表示法表示算法运行时间

大O表示法用来度量一个算法的运行时间。书写为O(n)&#xff0c;其中n为一个算法所执行的操作次数。当我们讨论算法的运行时间时&#xff0c;说的是一个算法在给定的输入列表增加的情况下算法执行操作数的增速&#xff0c;也就是运行时间的增速。 二分查找算法 下面介绍两种简…

锐捷设备密码管理、密码恢复、恢复出厂设置

目录 配置登录用户名密码以及Enable密码 只需要密码登录 需要用户名和密码登录&#xff08;无AAA&#xff09; 需要用户名和密码登录&#xff08;有AAA&#xff09; 密码恢复 Web密码忘记 Telnet/SSH密码忘记 Console密码忘记 所有密码都忘记&#xff0c;通过Console进…

Java GUI,mybatis实现资产管理系统

Java GUI——资产管理系统 前言&#xff1a;为了做java课设&#xff0c;学了一手Java GUI。感觉蛮有意思的&#xff0c;写写文章&#xff0c;做个视频记录一下。欢迎大家友善指出我的不足 资产管理系统录制视频&#xff0c;从头敲到尾 模块划分 资产信息管理 资产信息查询 …