树与图的dfs

本文介绍了深度优先搜索(DFS)的概念,提供了DFS的基本代码模板,并通过一道例题展示了如何使用DFS解决树的重心问题。在给定的树结构中,DFS遍历寻找树的重心,删除后使得各连通块点数最大值最小的节点。通过DFS遍历,实现了O(n)的时间复杂度解题策略。
摘要由CSDN通过智能技术生成

目录

一、dfs是什么?

        dfs(Depth First Search)叫做深度优先搜索,又叫深度优先遍历

二、代码模板

代码如下:

void dfs(int u) {
    st[u] = true;
    for(int i = h[u]; i != -1; i = ne[i]) {
        int j = ne[i];
        if(st[j]) continue;
        dfs(j) ... ;
    }
}

三、例题引入

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

输入格式

第一行包含整数 n,表示树的结点数。

接下来 n−1行,每行包含两个整数 a 和 b,表示点 a 和点 b 之间存在一条边。

输出格式

输出一个整数 m,表示将重心删除后,剩余各个连通块中点数的最大值。

数据范围

1≤n≤1e5

输入样例

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

输出样例

4

 思路:

01-利用链式前向星存储题目数据

02-利用dfs模板进行遍历

03-因为会遍历每个点,故时间复杂度为O(n) 

#include <iostream>
#include <cstring>

using namespace std;

const int N = 1e5 + 10, M = 2 * N; 

int h[N], e[M], ne[M], idx, n, ans = N;
bool st[N];

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

int dfs(int u) {
	st[u] = true;
	int sum = 0, size = 0; // sum 记录以u为根的树中的子树结点个数,size保存这些字数的结点个数最大值
	for(int i = h[u]; i != -1; i = ne[i]) {
		int j = e[i];
		if(st[j]) continue;
		int s = dfs(j);
		size = max(size, s);
		sum += s;
	}
	size = max(size, n - sum - 1);
	ans = min(ans, size); // ans记录最大的最小值
	return sum + 1;
}

int main() {
    memset(h, -1, sizeof h);
	cin >> n;
	for(int i = 0; i < n; i++) {
		int a, b;
		scanf("%d%d", &a, &b);
		add(a, b), add(b, a);
	}
	dfs(1);
	cout << ans << endl;
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值