树与图的深度优先遍历
DFS遍历方式
每个节点只遍历一次,开一个标记数组——bool state[N];
例题1:数的重心 AW846
- 递归过程为
int dfs(int u)
{
state[u]=true;
int sum=1,res=0;
for(int i=h[u];i!=-1;i=ne[i]) //一直走到链表底,符合DFS
{
int j=e[i];
if(!state[j])
{
int s=dfs(j);
res=max(res,s);
sum+=s; //sum每次初始化的时候值为1,也就是每次递归过程从底部开始会向上记录其父节点子树节点的个数
}
}
res=max(res,n-sum);//某结点上面连通块的点数值为:n - (当前点的子树的点数)
ans=min(ans,res); //找最小值进行输出
return sum; //返回值的意义是传sum值到下一层,因为下一层的局部变量res值为0
}
- 枚举每个点被去掉之后剩余连通块点的个数,再算最大值
如下图所示,结点4上面连通块的点数值为:n - (4子树的点数)
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=100003,M=N*2; //边的数量最多能达到两倍
int n;
int h[N],e[M],ne[M],idx; //h存n个链表的链表头
//之后三个是链表基本结构:节点上的值,存储下一个节点,当前处理到了哪
bool state[N]; //每个节点只遍历一次,开一个标记数组
int ans=N; //存放答案,要存全局变量
void add(int a,int b) //单链表基本操作
{
e[idx]&