luogu P2016 战略游戏 树形dp

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=3010;
int e[N],h[N],ne[N],idx;
int f[N][2];
bool st[N];
void add(int a,int b)
{
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
int n,m;
int a,b;
void dfs(int u)
{
	f[u][1]=1;
	f[u][0]=0;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		dfs(j);
		f[u][0]+=f[j][1];
		f[u][1]+=min(f[j][0],f[j][1]);
	}
}
int main()
{
	idx=0;
	memset(h,-1,sizeof h);
	memset(st,0,sizeof st);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int id,cnt;
		cin>>id>>cnt;
		while(cnt--)
		{
			int ver;
			cin>>ver;
			add(id,ver);
			st[ver]=1;
		}
	}
	int root=0;
	while(st[root])
		root++;
	dfs(root);
	cout<<min(f[root][1],f[root][0])<<endl;
	return 0;
}

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12568454.html

时间: 2024-07-30 07:37:07

luogu P2016 战略游戏 树形dp的相关文章

P2016 战略游戏——树形DP大水题

P2016 战略游戏 树形DP 入门题吧(现在怎么是蓝色标签搞不懂): 注意是看见每一条边而不是每一个点(因为这里错了好几次): #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=3010; int pre[maxn],last[maxn],other[maxn],l; void add(int x,int y) { l++; pre[l]

luogu#P2016 战略游戏

题意: 给出一棵有 \(N\) 个节点的树,节点编号 \(0\) ~ \(N-1\) .如果在一个节点上放置一个士兵,那么该节点及与该节点相连的所有节点都可以被瞭望到.求瞭望到所有节点所需的最少的士兵数. 解法: 树形dp 设 \(f[i][j]\) = 节点 \(i\) 选(\(j=1\))不选(\(j=0\))的最少需要的士兵 因为对于一个节点 \(i\) ,如果它不选,那么必须选与它相连的点的其中一个,则: f[x][1]+=min(f[v][0],f[v][1]); //设v是与x相邻的

【Luogu】P3565HOT-Hotels(树形DP)

题目链接 水了半个月之后Fd终于开始做题啦! 然后成功的发现自己什么都不会了 树形DP,既然是三个点两两距离相等那一定得有个中心点吧,枚举那个中心点,然后暴力DFS,根据乘法原理算. 乘法原理就是我一个子树,距离为i的选择情况增加tot[i],两个子树的话是一个子树的选择情况乘上tot[i],三个子树(就是答案)就是两个子树的选择情况乘上tot[i]; 挺暴力的……不过貌似POI能过了 据说有个加强版100000数据范围,要什么长链剖分……记一下以后来填坑 #include<cstdio> #

P2016 战略游戏

一道还算比较好写的"求树的最大独立集"的问题. f [ x ] [ 0 ] 表示以x为节点的子树上,在x位置不放士兵时,士兵数量的最小值: f [ x ] [ 1 ] 表示以x为节点的子树上,在x位置要放士兵时,士兵数量的最小值: 那么方程就写出来了,在回溯的时候,对于f [ x ] [ 0 ] ,它的子节点一定都要放,累加f [ x ] [ 1 ] :那么对于f [ x ] [ 1 ] ,取最小值就可以了. 注意边界判断,当你到树的叶子的时候,要在操作 f 之后返回. 代码如下: #

4.9 省选模拟赛 圆圈游戏 树形dp set优化建图

由于圆不存在相交的关系 所以包容关系形成了树的形态 其实是一个森林 不过加一个0点 就变成了树. 考虑对于每个圆都求出最近的包容它的点 即他的父亲.然后树形dp即可.暴力建图n^2. const int MAXN=100010; int n,m,len; struct wy { ll x,y,r,w; inline int friend operator <(wy a,wy b){return a.r<b.r;} }t[MAXN]; int f[MAXN]; int lin[MAXN],ver

【Luogu】P2016战略游戏(树形DP)

题目链接 设f[i][j]表示以节点i为根的子树在状态j的情况下的最优解. j有两种情况. j=1:i这个根节点有士兵在站岗. j=0:i这个根节点没有士兵在站岗. 转移方程很好想. f[x][1]+=min(f[to][0],f[to][1]); f[x][0]+=f[to][1]; 这样子. 意思就是:如果根节点已经有人站岗了,那么它的直接子节点可站可不站.就从子节点的两种状态中选一个小的. 如果根节点没有人站岗,那它的所有直接子节点都必须站岗,否则会有道路有人看不到. 代码奉上. #inc

Luogu P1273 有线电视网(树形dp+背包)

题面 题目描述 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构,这棵树的根结点位于足球比赛的现场,树叶为各个用户终端,其他中转站为该树的内部节点. 从转播站到转播站以及从转播站到所有用户终端的信号传输费用都是已知的,一场转播的总费用等于传输信号的费用总和. 现在每个用户都准备了一笔费用想观看这场精彩的足球比赛,有线电视网有权决定给哪些用户提供信号而不给哪些用户提供信号. 写一个程序找出一个方案使得有线电视网在不亏本的情况下使观看转播的用户尽可能多. 输入输出格

[luoguP2016] 战略游戏(DP)

传送门 f[i][0]表示不选当前节点,当前节点的所有儿子节点都选f[i][1]表示选当前节点,儿子节点可选可不选 #include <cstdio> #include <cstring> #include <iostream> #define N 1501 #define min(x, y) ((x) < (y) ? (x) : (y)) int n, cnt; int head[N], to[N << 1], next[N << 1],

树形dp 入门

今天学了树形dp,发现树形dp就是入门难一些,于是好心的我便立志要发一篇树形dp入门的博客了. 树形dp的概念什么的,相信大家都已经明白,这里就不再多说.直接上例题. 一.常规树形DP P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了.所以