SSL1608 皇宫看守【树形DP】

在这里插入图片描述

思路

f [ i ] [ 0 ] f[i][0] f[i][0] 表示当前节点站士兵;
f [ i ] [ 1 ] f[i][1] f[i][1] 表示当前节点不站士兵,被他其中一个子节点监视。
f [ i ] [ 2 ] f[i][2] f[i][2] 表示当前节点不站士兵,被父节点监视。


首先,我们考虑 f [ i ] [ 0 ] f[i][0] f[i][0]
如果它当前放守卫,
那么它的儿子节点可放可不放,都会被监视。
于是,我们就有:
f [ x ] [ 0 ] + = m i n ( f [ y ] [ 0 ] , m i n ( f [ y ] [ 1 ] , f [ y ] [ 2 ] ) ) ; f[x][0]+=min(f[y][0],min(f[y][1],f[y][2])); f[x][0]+=min(f[y][0],min(f[y][1],f[y][2]));


然后,我们思考 f [ i ] [ 1 ] f[i][1] f[i][1]
它被它的子节点监视,也就是不去监视它儿子,
那我们可以在它儿子这里放守卫,或者在它儿子的儿子放守卫,就会监视到它儿子。
然后我们思考,
当前 x x x 必须要被其中一个儿子监视,
也就是说要在它众多儿子中选一个出来监视,
于是这个儿子就必须放守卫,我们就有:

for(int i=ls[x]; i; i=a[i].next)
	 {
    
    
	 	long long y=a[i].y;
	 	sum[y]=min(f[y][0],f[y][1]);
	 	js+=sum[y];
	 }
	f[x][1]=2147483647;
	for(int i=ls[x]; i; i=a[i].next)
	   f[x][1]=min(f[x][1],js-sum[a[i].y]+f[a[i].y][0]);

最后我们思考 f [ i ] [ 2 ] f[i][2] f[i][2]
它被父亲监视,也就是说它儿子必须被它儿子的儿子监视,
这样它儿子才不会监视到它。最后我们就有:
f [ x ] [ 2 ] + = f [ y ] [ 1 ] ; f[x][2]+=f[y][1]; f[x][2]+=f[y][1];

猜你喜欢

转载自blog.csdn.net/Jackma_mayichao/article/details/108000988