#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;
}