当前位置:   article > 正文

【图论】图的存储--链式前向星存图法以及深度优先遍历图

【图论】图的存储--链式前向星存图法以及深度优先遍历图

图的存储

介绍

无向图-就是一种特殊的有向图->

只用考虑有向图的存储即可

有向图

  • 邻接矩阵
  • 邻接表

邻接表

在这里插入图片描述

存储结构:
(为每一个点开了一个单链表,存储这个点可以到达哪个点)

  • 1:3->4->null
  • 2:1->4->null
  • 3:4->null
  • 4:null
插入一条新的边

在这里插入图片描述

比如要插一条边:2->3

  • 先找到 2 对应的单链表
  • 然后将 3 插入到单链表里面去(一般使用头插)

对应的结构变化为:

  • 1:3->4->null
  • 2:3->1->4->null
  • 3:4->null
  • 4:null
插入边 Coding Part
#include <iostream>
#include <cstring>
#define p(e) print(e, sizeof(e)/sizeof(int))
using namespace std;

const int N = 100010, M = N * 2;
//N表示结点数量上限,M表示结点数值上限

int h[N], e[M], ne[M], idx;

//插入一个a->b
inline void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
	/*
		* idx是没有使用的空结点索引
		* 先给这个位置赋值b					# e[idx] = b
		* 然后让这个结点指向头结点			# ne[idx] = h[a]
		* 然后再更新头结点 					# h[a] = idx++
		* 同时让idx移动到新的空结点索引中去 # idx++
	*/
}

inline void print(int arr[], int n) {
	for (int i = 0; i < n; i++) cout << arr[i] << ' ';
	cout << endl;
}

int main() {
	memset(h, -1, sizeof h);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

遍历图

深度优先方法遍历图
  • 需要使用一个bool数组存放是否遍历的状态
  • 然后进行深度优先遍历
#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010, M = N * 2;
//N表示结点数量上限,M表示结点数值上限

int h[N], e[M], ne[M], idx;
bool st[N];
//插入一个a->b
inline void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
	/*
		* idx是没有使用的空结点索引
		* 先给这个位置赋值b					# e[idx] = b
		* 然后让这个结点指向头结点			# ne[idx] = h[a]
		* 然后再更新头结点 					# h[a] = idx++
		* 同时让idx移动到新的空结点索引中去 # idx++
	*/
}

inline void dfs(int u) {
	st[u] = true;
	cout << u << ' ' ;
	for (int i = h[u]; i != -1; i=ne[i]) {
		int j = e[i];
		if (!st[j]) dfs(j);
	}
}

int main() {
	memset(h, -1, sizeof h);
	memset(st, false, sizeof st);
	add(1, 3);
	add(3, 5);
	add(3, 6);
	add(1, 2);
	add(1, 8);
	dfs(1);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
题目:树的重心

给定一棵树,树中包含n个结点,(编号为1~n)和n-1个无向边
请找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。
重心定义:重心是指树中的一个结点,如果将这个结点删除后,剩余各个连通块中点数的最大值最小,那么这个结点被称为树的重心。
输入格式
第一行包含整数 n,表示树的结点数。
接下来 n-1 行,每行包含两个整数 ab,表示 ab 之前存在的一条边。

输出格式
输出一个整数 m,表示重心的所有子树中最大子树的结点数目。

数据范围
1 <= n <= 105

输入样例

9
1 2
1 7
1 4
2 8
2 5
4 3
3 9
4 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

输出样例

4
  • 1

答案代码

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100001, M = N*2;
int h[N], e[M], ne[M], idx;
bool st[N];

//a->b
void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

/*遍历模板*/
void dfs_template(int u) {
	st[u] = true;
	cout << u << ' ';
	for (int i = h[u]; i != -1; i = ne[i]) {
		int j = e[i];
		if (!st[j]) {
			dfs_template(j);
		}
	}
}

int n;										//n为题目输入的结点数量
int ans = INT_MAX;							//初始化题目要求的最小值
int dfs(int u) {
	//每一棵树找到最大连通块的数量
	st[u] = true;
	int sum = 1, res = 0;							//sum统计子结点(包括自己)的数量, res统计儿子树最大连通块数量
	for (int i = h[u]; i != -1; i = ne[i]) {
		int j = e[i];
		if (!st[j]) {
			int s = dfs(j);
			sum += s;							//加上子节点的数量
			res = max(s, res);					//找到子树中的最大连通块
		}
	}
	res = max(res, n-sum);							//和父亲树进行比较
	ans = min(ans, res);							//更新答案
	return sum;
}

int main() {
	memset(h, -1, sizeof ne);
	cin >> n;
	for (int i = 0; i < n-1; i++) {
		int a, b;
		cin >> a >> b;
		add(a, b), add(b, a);
	}
	dfs(1);
	cout << ans << endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
宽度优先方法遍历图

补充两个图论的概念:

  • 重边: 例如,存在两条 1->2 的边,叫重边
  • 自环:例如,1->1叫自环
题目:图中点的层次
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/419924
推荐阅读
相关标签
  

闽ICP备14008679号