UVA 1292-Strategic game(树形DP)

题目大意:给出一棵树,在某个选择某个结点可以覆盖和它相连的所有边,问最少选多少个结点所有边都被覆盖。

首先将无根树转化为有根树,0为根。

用d[i][0]表示不选择结点i时覆盖以结点i为根的子树最少要多少个结点,用d[i][1]表示选择结点i时覆盖以结点i为根的子树最少要多少个结点。若结点i不选,为了和覆盖所有和结点i相连的结点,则每个儿子都必须选,若结点i选,则每个儿子选择较小的那个值。按DFS顺序递推。

状态转移方程:

d[i][0]=sum { d[u][1] }(u是i的儿子)

d[i][1]=sum { min { d[u][0],d[u][1] } }+1(u是i的儿子)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std;
int a[30];
int d[1510][2];
char e[1510];
int par[1510];
vector<int> G[1510];
void dfs(int u);
void rootedtree(int u,int fa);
int main(void)
{
	int i,j,u,n,sump,top,lo;
	while(scanf("%d",&n)==1)
	{
		for(i=0;i<n;i++)
		{
			G[i].clear();
		}
		for(i=1;i<=n;i++)
		{
			scanf("%s",e);
			lo=strlen(e);
			j=top=0;
			while(j<lo)
			{
				if((e[j]>='0')&&(e[j]<='9'))
				{
					sump=0;
					while((e[j]>='0')&&(e[j]<='9'))
					{
						sump=sump*10+e[j]-'0';
						j++;
					}
					top++;
					a[top]=sump;
				}
				else
				{
					j++;
				}
			}
			for(j=1;j<=a[2];j++)
			{
				scanf("%d",&u);
				G[a[1]].push_back(u);
				G[u].push_back(a[1]);
			}
		}
		rootedtree(0,-1);
		for(i=0;i<n;i++)
		{
			G[i].clear();
		}
		for(i=1;i<n;i++)
		{
			G[par[i]].push_back(i);
		}
		dfs(0);
		printf("%d\n",d[0][0]>d[0][1]?d[0][1]:d[0][0]);
	}
	return 0;
}
void dfs(int u)
{
	int i,p,minp,sump;
	p=G[u].size();
	if(p==0)
	{
		d[u][0]=0;
		d[u][1]=1;
	}
	else
	{
		for(i=0;i<p;i++)
		{
			dfs(G[u][i]);
		}
		sump=minp=0;
		for(i=0;i<p;i++)
		{
			minp=minp+(d[G[u][i]][0]>d[G[u][i]][1]?d[G[u][i]][1]:d[G[u][i]][0]);
			sump=sump+d[G[u][i]][1];
		}
		d[u][0]=sump;
		d[u][1]=minp+1;
	}
}
void rootedtree(int u,int fa)
{
	int i,v,p;
	p=G[u].size();
	for(i=0;i<p;i++)
	{
		v=G[u][i];
		if(v!=fa)
		{
			par[v]=u;
			rootedtree(v,u);
		}
	}
}
时间: 2024-10-14 04:55:03

UVA 1292-Strategic game(树形DP)的相关文章

uva 12186 Another Crisis 树形dp

// uva 12186 Another Crisis 树形dp // // 对于一个节点u,有k个子节点,则至少有c = (k * T - 1) / 100 + 1才能 // 发信,即c / k >= T / 100,则 c 的值为 k * T /100,上取整变成上式 // 将所有的子节点d从小到大排序,取前c个就是d[u]的值 // 紫书上的一题,之前看了好久好久,觉得挺好的,然而一直没做,今天就来 // 体验体验,挺好的一题,注意一下,如果一个节点是叶节点,直接return 1就好 //

Strategic Game(树形DP)

目录 Strategic Game(树形DP) 题目 题意 思路 题解 Strategic Game(树形DP) 题目 Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad. Now he has the following problem. He must defend

UVA - 1218 Perfect Service(树形dp)

题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连接且仅仅能连接一台server(不包含作为server的电脑).求最少须要多少台电脑作为server. 思路 典型的树形dp问题,那么我们来建立模型. d(u,0):u是server,孩子是不是server均可 d(u,1):u不是server,u的父亲是server,u的孩子不能是server d(u,2)

POJ 3398 / UVA 1218 Perfect Service 树形DP

树形DP Perfect Service Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1378   Accepted: 668 Description A network is composed of N computers connected by N ? 1 communication links such that any two computers can be communicated via a uniqu

UVA 10859 Placing Lampposts 树形dp(水

题目链接:点击打开链接 题意: 白书P70 思路: 简单题,每个点分放或不放. import java.io.PrintWriter; import java.util.ArrayList; import java.util.Scanner; public class Main { int min(int a,int b){return a>b?b:a;} int max(int a,int b){return a>b?a:b;} static int N = 1005; static int

UVA 10859 - Placing Lampposts 树形DP、取双优值

                          Placing Lampposts As a part of the mission ‘Beauti?cation of Dhaka City’, the government has decided to replace all theold lampposts with new expensive ones. Since the new ones are quite expensive and the budget is notup to

POJ 1463 Strategic game( 树形DP )

题意:一颗 N 个节点的树,在某一个节点上放置一个兵则可以守住与它相邻的边.最少放置多少个兵才可以守住所有的边. #include <cstdio> #include <deque> using namespace std; #define ABANDON 0 #define GET 1 deque< int > graph[2010]; int DP[2010][2]; void DFS( int start, int parent ){ DP[start][ABAN

HDU 1054 Strategic Game (树形dp)

题目链接 题意: 给一颗树,用最少的点覆盖整棵树. 分析: 1:以当前节点为根节点,在该节点排士兵守护道路的最小消耗.在这种情况下,他的子节点可以安排士兵,也可以不安排士兵.可以从各个子节点两个不同状态(存在士兵,不存在士兵)的最值中选出最小的消耗,然后相加就求出了当前节点派士兵的最小消耗. 2:以当前节点为根节点,不存在士兵.这种情况十分清楚,因为当前节点没有士兵,那么这个节点到子节点之间的道路没有人守护,那么子节点就必须要安排士兵,因此这种情况下.这个节点的最小消耗就是每个子节点存在士兵的情

UVA 10859 Placing Lampposts 树形DP

dfs+记忆化搜索,白书上给了一种很神的存答案的方式,要同时保存两个值,可以将一个值乘以一个大整数加上另外一个. 具体状态转移见注释 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue>