基环树
树形dp
1.并查集查环
int find(int x){
return x==p[x]?p[x]:p[x]=find(p[x]);
}
2.若可以合并,则连边,若为环,则存储环的某条边(存两个点)
int a=find(i),b=find(x);
if (a==b) {
u[tot]=i;
v[tot++]=x;
}
else {
p[a]=b;
G[i].push_back(x);
G[x].push_back(i);
}
查环,遍历每个基环树,求ans
for (int i=0;i<tot;i++){
dfs(u[i],-1);
tmp=dp[u[i]][0];
dfs(v[i],-1);
tmp=max(tmp,dp[v[i]][0]);
ans+=tmp;
}
4.树形dp过程
void dfs(int u,int fa){
dp[u][0]=0;
dp[u][1]=a[u];
for (int i=0;i<G[u].size();i++){
int v=G[u][i];
if (v==fa) continue;
dfs(v,u);
dp[u][0]+=max(dp[v][0],dp[v][1]);
dp[u][1]+=dp[v][0];
}
}