结点覆盖
解题思路
这是一道树形DP。
设
f
i
,
0
f_{i,0}
fi,0 表示以
i
i
i 为根的子树全部被覆盖,
i
i
i 的父亲被选的最小值。
f
i
,
1
f_{i,1}
fi,1 表示
i
i
i 被选的最小值。
f
i
,
2
f_{i,2}
fi,2 表示
i
i
i 的儿子被选在最小值。
code
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int a[2010];
int f[2010][3];
int hd[2010],tot;
struct abc{
int to,nxt;
}b[3010];
void add(int x,int y)
{
b[++tot]=(abc){y,hd[x]};
hd[x]=tot;
}
void dfs(int x,int fa)
{
int minn=0x3f3f3f3f;
f[x][1]=a[x];
for(int i=hd[x];i;i=b[i].nxt)
{
int y=b[i].to;
if(y==fa) continue;
dfs(y,x);
f[x][0]+=min(f[y][1],f[y][2]);
f[x][1]+=min(f[y][0],min(f[y][1],f[y][2]));
f[x][2]+=min(f[y][1],f[y][2]);
minn=min(minn,(f[y][1]<f[y][2]?0:f[y][1]-f[y][2]));
}
f[x][2]+=minn;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
int x,y,m;
scanf("%d",&x);
scanf("%d%d",&a[x],&m);
for(int j=1;j<=m;j++)
{
scanf("%d",&y);
add(x,y),add(y,x);
}
}
dfs(1,0);
printf("%d",min(f[1][1],f[1][2]));
}