ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

复杂树形DP 题解

2021-01-13 20:03:28  阅读:147  来源: 互联网

标签:min int 题解 树形 sons fte 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有