一、结构体定义及初始化方法
struct edge
{
int to,next;
//to: 第i条边(x,y)的指向y
//next: 与x连接的上一条边
};
edge e[100004];
int cnt=1;
int head[100004];
void add(int x,int y)
{
e[cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt;//更新与x相连的边为cnt
cnt++;
}
二、常见考法(洛谷)
1. 左孩子右孩子
题目要求:给定多叉树T,求T以左孩子右孩子方法变成二叉树的最大高度。
其实就是求根节点的子节点个数+最高的子树高度(递推地来看,这个最高地子树高度其实也是它地子节点个数)
void dfs(int x)//遍历以x为根节点的树
{
int height=0;
for(int i=head[x];i;i=e[i].next)//这样可以遍历以x为根节点的下一层的所有子节点。
{
int v=e[i].to;
dfs(v);
height++;//遍历到一个子节点height++
dp[x]=max(dp[x],dp[v]);
//cout<<"当前遍历"<<v<<"结点,height="<<height<<" dp["<<x<<"]="<<dp[x]<<endl;
}
dp[x]+=height;//dp[2] = 1
}
注意:本题有明确父子关系,所以add(x,y)只需要一次
2. 最大子树和 / 生命之树
题目本意都是让在T中找到T’,拥有最大加权和。
void dfs(int x,int fa)//以x为根节点构成S。
{
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
dfs(v,x);
if(dp[v]>0)
{
dp[x]+=dp[v];
}
}
}
}
注意:像这样没有明显父子关系的树,add(x,y)需要做双向。
并且dfs格式需要写明x和fa,即建树时缺失的顺序需要在这里阐明。