树与图的深度优先遍历

深度优先遍历

#include <iostream>

using namespace std;

const int N = 100010;
const int M = N * 2;
 

// 树和图的存储用邻接表
// N个点用N个单链表,单链表存储的为该点能直接到达的点
int h[N], e[M], ne[M], idx;

bool st[N]; // true表示该点已经被搜索过了

// 插入一条 a->b 的边
void insert(int a, int b)
{
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx;
	idx++;
}


// 深度优先搜索
void dfs(int u)
{
	// 当前点已经搜索过了
	st[u] = true;

	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);

	return 0;
}

深度优先遍历例题

#include <iostream>

using namespace std;

const int N = 100010;
const int M = N * 2;

/*

给定一颗树,树中包含 n 个结点(编号1~n)和 n-1 条无向边请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。
重心定义:重心是指树中的一个结点,如果将这个点删除后,剩余各个连通块中点数的最大值最小,那么这个节点被称为树的重心。

输入格式:
第一行包含整数n,表示树的结点数
接下来n-1行,每行包含两个整数a和b,表示点a和点b之前存在一条边。

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

*/


// 定义邻接链表
int h[N], e[M], ne[M], idx;
int n;

// 全局变量记录最终答案
int ans = N;

// 插入一条边
void insert(int a, int b)
{
	e[idx] = b;
	ne[idx] = h[a];
	h[a] = idx;
	idx++;
}

// 返回以 u 为根的子树的点数
int dfs(int u)
{
	int sum = 1; // 记录已当前节点为根的树的点数,等于 1 + 各子树点数
	int res = 0; // 记录删除当前节点后各连通树点数的最大值

	// 遍历当前节点的子节点
	for (int i = h[u]; i != -1; i = ne[i])
	{
		int j = e[i];
		int s = dfs(j);
		sum += s;
		res = max(res, s);
	}

	res = max(n - sum, res);
	ans = min(res, ans);

	return sum;
}


int main()
{
	memset(h, -1, sizeof h);

	cin >> n;

	for (int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin >> a >> b;

		insert(a, b);
	}

	dfs(1);

	cout << ans << endl;

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值