题解 | #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;
}
全部评论

相关推荐

01-17 18:15
已编辑
门头沟学院 前端工程师
从上午约我面试然后他迟到,然后中午发消息打电话给我说重约面试时间,我就该意识到。【管理不规范,只是这家公司最小的问题】他妈一个不是技术的人来给我技术面。。。连vvue什么?连react是什么?连普通的HTTP请求是什么?这些东西都不懂的人来给我做技术面,我真的。。。。他妈浪费我40分钟。。一天面了三场,这家公司属实牛逼。不停的问我说上班下班时间谁来派任务公司在哪个区发展怎么样,公司的管理模式什么样,培养机制怎么样带教负责什么。如果出bug了谁来负责。我真的求你了别闹了。我答了15分钟,我已经很不想回答了。然后他就问了我一些很招笑的面试问题。问我前端框架架构设计怎么设计,Websocket可以实现SSE吗??最后还要我硬说,为什么我们公司没转正?为什么?为什么?我说我怎么知道。。这是领导决定,又不是我决定,他说让我分析一下。。。我真的草了,这个人是来搞我的吗?我最后问我说这个没有技术面,他说他就是技术面虽然我今天面的另外两家也很逆天。一个人不停的吹牛,自己100人的公司是全国前几,吹牛了一个小时。我中途几次想跑,真的是底下玩手机在听他那吹牛。。然后最后来了句说,我承诺的东西要实现哦,不然的话,公司会追责的,我我请问我承诺了什么?从头到尾也没有说让我承诺什么。而且我只是作为一个小小的前端卡拉咪,应届生。我要承担什么??好崩溃。。好崩溃的,一天面了三场。两家1000-9999的公司。面试官问的都很傻逼,甚至有些东西我问他估计都答不出来。。&nbsp;我这是在干嘛呀?浪费我一天的时间,我的奶奶。。我本来是抱着说我很菜,我要面试中发现自己的问题,现在来看他妈的这三场面试,面试本身就是问题。。
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务