社区讨论

树形dp站外题求助

学术版参与者 3已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@lo123ew0
此快照首次捕获于
2023/10/22 13:56
2 年前
此快照最后确认于
2023/11/02 13:26
2 年前
查看原帖
可以在here提交,登陆不需验证邮箱,玄5关(前提是让我AC
CPP
很久以前,在一个神奇的神话国度中,存在着N座美丽的城镇,它们散落在广袤的仙境之中。这些城镇由神话之树相互连接,神话之树是这个仙境的生命之源,它的树枝代表着城镇之间的神秘联系。

然而,仙境中的居民开始感到担忧,因为疾病和伤害可能威胁到他们的神话国度。因此,仙境的守护者决定在某些城镇中建造神庙来照料城镇的居民,每个神庙能够守护相邻的城镇和自己的城镇,但他们希望尽量减少神庙的数量,以保持仙境的纯净和神秘。

你被赋予了神秘的任务,帮助守护者确定最少需要建造多少座神庙,以确保整个神话国度的每个城镇都能获得及时的神秘疗愈。神话之树将为你提供城镇之间的神秘联系。你能够揭示这个古老神秘国度的答案吗?
CPP
#include<bits/stdc++.h>
using namespace std;
struct pth{
	int next,to;
};
pth a[10005];
int n,head[10005],cnt;
void add(int x,int y)
{
	cnt++;
	a[cnt].to=y;
	a[cnt].next=head[x];
	head[x]=cnt;
}
int dp[10005][3];
void trdp(int f,int x)
{
	int cnt=0;
	for(int i=head[x];i;i=a[i].next)
	{
		int u=a[i].to;
		if(u==f)continue;
		cnt++;
		trdp(x,u);
	}
	if(cnt==0){dp[x][0]=0;dp[x][1]=1;return;}
	bool fl=0;
	dp[x][1]=1;
	for(int i=head[x];i;i=a[i].next)
	{
		int u=a[i].to;
		if(u==f)continue;
		dp[x][1]+=min(dp[u][0],dp[u][1]);
//			if(x==1)
//			{
//				printf("%d %d\n",dp[u][0],dp[u][1]);
//			}
		if(dp[u][1]<=dp[u][0])fl=1;
	}
	int maxx=INT_MAX,maxid=0;
	if(fl)dp[x][0]=dp[x][1]-1;else
	{
		for(int i=head[x];i;i=a[i].next)
		{
				int u=a[i].to;
		if(u==f)continue;
			if(dp[u][1]<maxx)maxx=dp[u][1],maxid=u;
		}
		dp[x][0]=dp[x][1]-1-dp[maxid][0]+dp[maxid][1];			
	}
}
int main()
{
//	freopen("hos8.in","r",stdin);
//	freopen("cnm.txt","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int x,y;cin>>x>>y;add(x,y);
	}
	trdp(-1,1);
	printf("%d\n",min(dp[1][1],dp[1][0]));

//	printf("\n\n\n\n\n\n\n\n");
//	for(int i=1;i<=n;i++)printf("%d %d\n",dp[i][0],dp[i][1]);
}
CPP
in:

7
1 2
1 5
2 3
3 4
5 6
6 7
out:

3

回复

8 条回复,欢迎继续交流。

正在加载回复...