题解 | #Strategic game#

Strategic game

https://ac.nowcoder.com/acm/problem/51222

Strategic game

题意:

给你一棵树,已知于某点放一个士兵,则与之相连的边就都能被“看守”,问使所有边都能有人看守至少要放置多少士兵。(本题为多组输入)

【与“没有上司的舞会”神似,经典树形dp】

思路:

树形dp为类似“树的后序遍历”的dfs, 由叶结点向根结点转移

一条边要被看守,则其两端点至少要有一点有士兵。设 f[i] 为以 i 为根节点的子树所需最少士兵数,i 点有两种状态:放或不放。对于一条边,若 i 放置士兵,则该边所连的 i 的子结点可放可不放,取最小的一种;若 i 不放,则另一点必须放(否则这条边就无人看守了)。f[i][1]为放置,f[i][0]不放。则状态转移方程:

		f[i][1]=1+Σ(max(f[j][1],f[j][0]));
        f[i][0]=Σ(f[j][1]);

代码的实现上有两种写法:

一、单向边,求出根(root)再从root开始dfs

#include<algorithm>
#include<vector>
using namespace std;
const int M=1510;
int n,f[M][2];
vector<int> son[M];
void dfs(int i){
	f[i][1]=1;     //保证边界正确,就算为叶结点,后面的不执行,也正确。
	for(int x=0;x<son[i].size();x++){
		int j=son[i][x];
		dfs(j);
		f[i][1] += min(f[j][0],f[j][1]);
		f[i][0] += f[j][1];
	}
}
int main(){
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			f[i][1]=f[i][0]=0;
			son[i].clear();
		}
		int root=n*(n-1)/2;  //先把所有点的和求出来
		for(int i=0,x,m;i<n;i++){
			scanf("%d:(%d)",&x,&m);
			for(int j=0,y;j<m;j++){
				scanf("%d",&y);//y是x的子节点
				root -= y;    //再依次减去子节点,最后剩下的就是根结点
				son[x].push_back(y);
			}
		}
		dfs(root);
		printf("%d\n",min(f[root][1],f[root][0]));
	}
	return 0;
}

二、存双向边,可以任意点为根结点开始搜索

#include<algorithm>
#include<vector>
using namespace std;
const int M=1510;
int n,f[M][2];
vector<int> son[M];
void dfs(int i,int fa){//定义一个fa(父亲)结点
	f[i][1]=1;
	for(int x=0;x<son[i].size();x++){
		int j=son[i][x];
		if(j==fa)continue;  //注意若与fa相等则不搜
		dfs(j,i);
		f[i][1] += min(f[j][0],f[j][1]);
		f[i][0] += f[j][1];
	}
}
int main(){
	while(~scanf("%d",&n)){//多组输入
		for(int i=0;i<n;i++){
			f[i][1]=f[i][0]=0;
			son[i].clear();  //清空
		}
		for(int i=0,x,m;i<n;i++){
			scanf("%d:(%d)",&x,&m);
			for(int j=0,y;j<m;j++){
				scanf("%d",&y);
				son[x].push_back(y);
				son[y].push_back(x);
			}
		}
		dfs(0,-1);    //这里以0为根结点搜
		printf("%d\n",min(f[0][1],f[0][0]));
	}
	return 0;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
02-25 17:03
点赞 评论 收藏
分享
我看标题以为40W,我觉得最差也得40k,点进去一看40块。你永远想不到客户的预算有多低...&nbsp;要求&ldquo;前端使用vue+element开发一个pc端宠物网站和vue+vant开发一个移动端网站,类型是宠物网站的。客户预算40&rdquo;&nbsp;全网最受欢迎的嵌入式面经面经一共32篇文章,12w+字数,包含全部最新的面试必问考点,4.7w+同学学习,2800+订阅,非常适合在找工作面经薄弱的同学,3000+订阅还会涨价,提前订阅提前享受,持续更新中。原帖链接:https://www.nowcoder.com/creation/manager/columnDetail/MJNwoMc
野猪不是猪🐗:哎呀,看来这位客户预算确实挺让人意外的呢!不过,别灰心,有时候客户的预算有限,但项目完成后说不定能带来意想不到的收获呢!😊 至于你提到的嵌入式面经,听起来好像很棒的样子!如果你对求职有帮助,那确实值得订阅学习哦!悄悄告诉你,点击我的头像,我们可以私信聊聊更多求职经验和技巧哦~🎉 对了,你对Vue和Element/Vant的开发有什么疑问或者想要分享的经验吗?我们可以一起探讨一下~😉
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务