其他分享
首页 > 其他分享> > 复杂树形DP 题解

复杂树形DP 题解

作者:互联网

复杂树形DP 题解

Analysis

一张图


  1. d ( u , 0 ) d(u,0) d(u,0): u u u是服务器,孩子是不是服务器均可
  2. d ( u , 1 ) d(u,1) d(u,1): u u u不是服务器, u u u的父亲是服务器, u u u的孩子不能是服务器
  3. d ( u , 2 ) d(u,2) d(u,2): u u u不是服务器且 u u u的父亲不是服务器, u u u的孩子必须有且仅有一个是服务器

状态转移方程:

  1. d p [ x ] [ 0 ] = ∑ m i n ( d p [ v ] [ 0 ] , d p [ v ] [ 1 ] ) + 1 , v ∈ s o n s dp[x][0]=\sum min(dp[v][0],dp[v][1])+1,v \in sons dp[x][0]=∑min(dp[v][0],dp[v][1])+1,v∈sons
  2. d p [ x ] [ 1 ] = ∑ d p [ v ] [ 2 ] , v ∈ s o n s dp[x][1]=\sum dp[v][2],v \in sons dp[x][1]=∑dp[v][2],v∈sons
  3. d p [ x ] [ 2 ] = m i n ( d p [ x ] [ 2 ] , d p [ v ] [ 0 ] + ∑ d p [ V i ] [ 2 ] ) dp[x][2]=min(dp[x][2],dp[v][0]+\sum dp[Vi][2]) dp[x][2]=min(dp[x][2],dp[v][0]+∑dp[Vi][2]) v ∈ s o n s , i ∈ s o n s , V i ≠ v v \in sons,i \in sons, Vi \neq v v∈sons,i∈sons,Vi​=v
优化狂魔: d p [ x ] [ 2 ] = m i n ( d p [ x ] [ 2 ] , d p [ x ] [ 1 ] − d [ v ] [ 2 ] + d [ v ] [ 0 ] ) , v ∈ s o n s dp[x][2]=min(dp[x][2],dp[x][1]-d[v][2]+d[v][0]),v \in sons dp[x][2]=min(dp[x][2],dp[x][1]−d[v][2]+d[v][0]),v∈sons

CODE

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int NR=1e4+5;
const int MR=1e5+5;
const int INF=0x3f3f3f3f;
const int MOD=1e9+7;
int n,u,v,op;
struct Edge
{
	int v,nxt;
}g[NR<<1];
int fte[NR],gsz;
void adde(int u,int v)
{
	g[++gsz]=(Edge){v,fte[u]};
	fte[u]=gsz;
}
int dp[NR][3];
void dfs(int x,int fa)
{
	
	dp[x][0]=1;
	dp[x][2]=NR;
	for(int i=fte[x];i;i=g[i].nxt)
	{
		int y=g[i].v;
		if(y==fa)
			continue;
		dfs(y,x);
		dp[x][0]+=min(dp[y][1],dp[y][0]);
		dp[x][1]+=dp[y][2];
	}
	for(int i=fte[x];i;i=g[i].nxt)
	{
		int y=g[i].v;
		if(y==fa)
			continue;
		dp[x][2]=min(dp[x][2],dp[y][0]+dp[x][1]-dp[y][2]);
	}
}
void solve()
{
	memset(fte,0,sizeof(fte));
	memset(dp,0,sizeof(dp));
	gsz=0;
    scanf("%d",&n);
	for(int i=1;i<n;++i)
	{
		scanf("%d%d",&u,&v);
		adde(u,v);
		adde(v,u);
	}
	dfs(1,1);
	printf("%d\n",min(dp[1][2],dp[1][0]));
}
int main()
{
	while(1)
	{
		solve();
		scanf("%d",&op);
		if(op==-1)
			break;
	}
	return 0;
}

标签:min,int,题解,树形,sons,fte,DP,服务器,dp
来源: https://blog.csdn.net/weixin_45643406/article/details/112587040