当前位置: 首页 > news >正文

浅说图论基础

引入

在学最短路算法之前,我们要先搞清楚另外一个事情,什么是图,我们又可以基于图做那些事情。

图不同于树,它是一种更加复杂的数据结构,相比较于树或者数组(线性表)而言,图的关联性显然更加强。比如说,在树中,一个点只有可能和他的父亲节点和他的儿子节点有直接的联系,但是在图中,任意两个点之间都有可能会有联系,也就是说节点之间的连通性是任意的。

同时,图也是包含了许多东西的,笼统的来说,图是包含树的,但是又不完全包含,因为图是允许有空边的(也就是说可以没有边),但是不能有空点的(也就是说至少也要有一个点),但是树是可以有空树的,线性表也是可以有空表的。

图可以干很多事,比如说我们这节课要学的最短路,除此之外,还有什么最小生成树啊,拓扑排序啊,这些都是图论,甚至于可以将一些不等式的求解或者是生活的一些实际问题放到图上来做,也就是我们后续也要讲的差分约束。

图论基础

图的存储

我们可以用两种方式来存储图,一种是邻接表,一种是链式前向星。不过我们最长用的还是邻接表,链式前向星其实没有太大的用处。所以说,我们还是使用邻接表吧,这个比较简单。

vector<int> mp[1000];
mp[u].push_back(v);

图的遍历

图还是和树一样,有深度优先遍历,也有广度优先遍历,其实实现的方法和之前的差不多,所以说可以直接写。

图的深度优先遍历

#include<bits/stdc++.h>
using namespace std;
const int INF=100000+10;
vector<int> mp[INF];
int used[INF];
int n,m;
void dfs(int x,int fa){
	used[x]=1;
	cout<<x<<" ";
	for (int i=0;i<mp[x].size();i++){
		if (used[mp[x][i]]==0){
			dfs(mp[x][i],x);
		}
	}
	return;
}
int main(){
	cin>>n>>m;
	for (int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		mp[u].push_back(v);
		mp[v].push_back(u);
	}
	dfs(1,-1);
	return 0;
}

图的广度优先遍历

#include<bits/stdc++.h>
using namespace std;
const int INF=100000+10;
vector<int> mp[INF];
int used[INF];
int n,m;
void bfs(int x){
	queue<int> q;
	q.push(x);
	used[x]=1;
	while (!q.empty()){
		x=q.front();
		cout<<x<<" ";
		q.pop();
		for (int i=0;i<mp[x].size();i++){
			if (used[mp[x][i]]==0){
				q.push(mp[x][i]);
				used[mp[x][i]]=1;
			}
		}
	}
}
int main(){
	cin>>n>>m;
	for (int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		mp[u].push_back(v);
		mp[v].push_back(u);
	}
	bfs(1);
	return 0;
}

图的联通性

对于一个图而言,如果任意两个点之间可以互相到达,那么就说明这个图是联通的。那么我们可以怎么检测一个图是否联通呢?其实很简单,我们直接从一个点出发,如果说可以到达所有点,那么这个图就一定是联通的,这也是上述定义的推论。下面以无向图为例子写一个代码:

#include<bits/stdc++.h>
using namespace std;
const int INF=100000+10;
vector<int> mp[INF];
int used[INF];
void dfs(int x){
	for (int i=0;i<mp[x].size();i++){
		if (used[mp[x][i]]==0){
			used[mp[x][i]]=1;
			dfs(mp[x][i]);
		}
	}
}
int main(){
	int n,m;
	cin>>n>>m;
	for (int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		mp[u].push_back(v);
		mp[v].push_back(u);
	}
	used[1]=1;
	dfs(1);
	for (int i=1;i<=n;i++){
		if (used[i]==0){
			cout<<"No";
			return 0;
		}
	}
	cout<<"Yes";
	return 0;
}

例题

A163 传递闭包

题目描述
给出一张 n n n 个节点的有向图,求任意两个节点之间是否可达。

输入格式
从标准输入读入数据。
第一行输入一个正整数 ( n ≤ 2000 ) (n≤2000) (n2000)

接下来 n n n 行,每行输入一个长度为 n n n 的 01 串,构成一个 n × n n×n n×n 的 01 矩阵 A A A,其中 A i j = 1 A_{ij} =1 Aij=1 代表 i i i j j j 有边,否则代表没有边。

输出格式
输出到标准输出。
输出 n n n 行,每行输出一个长度为 n n n 的 01 串,构成一个 n × n n×n n×n 的 01 矩阵 B B B,其中 B i j = 1 B_{ij} =1 Bij=1 代表 i i i j j j 可到达,否则代表不可到达。

样例1输入

4
0100
0110
1000
0101

样例1输出

1110
1110
1110
1111

分析——题解

其实这道题就是有向图的联通性问题,不过根据题目中所述,我们是要知道每个点可以到达哪个点的,所以说,我们可以从每个点出发,去看那些点合适,这样就对了,不过要注意一下,记得清空标记数组,否则十年OI一场空。

#include<bits/stdc++.h>
using namespace std;
int used[2100];
vector<int> mp[2100];

void dfs(int x){
	used[x]=1;
	for (int i=0;i<mp[x].size();i++){
		if (used[mp[x][i]]==0){
			used[mp[x][i]]=1;
			dfs(mp[x][i]);
		}
	}
}
int main(){
	int n;
	cin>>n;
	for (int i=1;i<=n;i++){
		for (int j=1;j<=n;j++){
			char ch;
			cin>>ch;
			if (ch=='1')mp[i].push_back(j);
		}
	}
	for (int i=1;i<=n;i++){
		dfs(i);
		for (int i=1;i<=n;i++){
			cout<<used[i];
		}
		cout<<endl;
		memset(used,0,sizeof(used));
	}
	return 0;
}
http://www.dtcms.com/a/56025.html

相关文章:

  • 数据库【MySQL安装配置篇(保姆级教程)】
  • 【go】以Kubernetes中的 kubelet 为引思考go语言中共享状态的选择
  • LeetCode 解题思路 12(Hot 100)
  • 使用ffmpeg读取mp4文件解码失败
  • 如何记录日常笔记
  • Django 中的算法应用与实现
  • LeetCode - 神经网络的 反向传播(Sigmoid + MSE) 教程
  • 玩转python: 掌握Python数据结构之链表
  • 安当全栈式金仓数据库安全解决方案:透明加密、动态凭据与勒索防护一体化实践
  • 【免费】2000.1-2021.9上市公司仲裁数据
  • TypeError: Cannot set properties of undefined (setting ‘xxx‘)
  • c++快速入门-2
  • 计算机网络-服务器模型
  • labelimg标注的xml标签转换为yolo格式标签
  • TMS320F28P550SJ9学习笔记4:导入其余包文件
  • 若依ry-vue分离板(完整版)前后端部署
  • AI革命先锋:DeepSeek与蓝耘通义万相2.1的无缝融合引领行业智能化变革
  • 元宇宙崛起:区块链与金融科技共绘数字新世界
  • RuleOS:DApp开发的“破局者”,区块链创新的“加速器
  • 从零开始的远程服务器跑深度学习(一)
  • 【基础1】冒泡排序
  • ERNIE 3.0: 大规模知识增强的预训练语言理解和生成框架
  • 【Minio】Docker部署Minio + 使用nginx配置https访问
  • 【漫话机器学习系列】124.感知机(Perceptron)
  • vue3中emits
  • 【预测】-双注意LSTM自动编码器记录
  • 职坐标机器学习编程实战:调试优化与自动化测试精要
  • 【C语言】指针篇
  • Python | 机器学习中最常用的超参数及使用示例
  • window系统中的start命令详解