UVA 10859 树形DP

很明显的树形DP了,设状态dp[i][0],dp[i][1]。枚举子节点放或不放的两种状态。

在此学到一种不同于一般处理的方法,题目要求被两灯照亮的边尽量多,反过来即被一灯照亮的尽量少设为e。又需要的灯尽量少设为v。

设M是一个很大的数,则M*v+e即是所求。由于M很大,所以主导作用取决于v,只要v不同M*v+e一定不会相同。当v相同,被一灯照亮的尽量少即v此时发挥作用。所以DP时只需要保存这种状态即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

int dp[1050][2];
bool vis[1050];
vector<int>t[1050];

const int M=2500;
int n,m;

void dfs(int u,int f){
	vis[u]=true;
	dp[u][1]=M;
	dp[u][0]=0;
	int sz=t[u].size();
	for(int i=0;i<sz;i++){
		if(t[u][i]!=f){
			dfs(t[u][i],u);
			dp[u][0]+=dp[t[u][i]][1]+1;
			dp[u][1]+=dp[t[u][i]][0]<dp[t[u][i]][1]?dp[t[u][i]][0]+1:dp[t[u][i]][1];
		}
	}
}

int main(){
	int T,u,v;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++)
		t[i].clear(),vis[i]=false;
		for(int i=1;i<=m;i++){
			scanf("%d%d",&u,&v);
			t[u].push_back(v);
			t[v].push_back(u);
		}
		int ans=0;
		for(int i=0;i<n;i++){
			if(!vis[i]){
				dfs(i,-1);
				ans+=min(dp[i][1],dp[i][0]);
			}
		}
		printf("%d %d %d\n",ans/M,m-ans%M,ans%M);
	}
	return 0;
}

  

时间: 2024-08-29 17:56:10

UVA 10859 树形DP的相关文章

Placing Lampposts - UVa 10859 树形dp

As a part of the mission ?Beautification of Dhaka City?, the government has decided to replace all the old lampposts with new expensive ones. Since the new ones are quite expensive and the budget is not up to the requirement, the government has decid

uva 1292(树形dp)

题意:有一个树,上面有n个结点,给出每个结点有边相连的直接相邻的点,问最少选几个点能让所有的边至少有一个结点被选中. 题解:树形dp简单题,把0当做根节点. f[i][0]:不选i点,覆盖所有边的最少点 f[i][1]:选i点,覆盖所有边的最少点 状态转移方程: f[u][1] += min(f[v][1], f[v][0]);//v是u的子节点,选u点子节点可以选或不选 f[u][0] += f[v][1];//不选u点就一定要选子节点,这样保证边能覆盖 #include <stdio.h>

uva 12223(树形dp)

题意:一个城市有n个景点,景点和景点之间的路线形成一棵无根树(也就是有n-1条边),给出景点之间的花费,一个人可以任选一个景点住在那里,然后他每年都要固定去m个景点,给出这m个景点和要去的次数,这个人每次去了景点都会回家,问他一年为了观赏景点最少花费多少钱. 题解:想了好久,看看题解才完全理解.要先把无根树转化成有根树,默认让1成为根节点,然后先dfs把每个节点v当做根节点的子树的节点数统计一下在num[v]中,因为计算u-v边的走到次数就是以v为根节点的子树的节点数的个数乘边的权值乘2(来回)

uva 10859 Placing Lampposts,树形dp

// uva 10859 Placing Lampposts // 树形dp // // 题目的意思是一个无向无环图中,有一些顶点和一些边 // 要在顶点上放置灯笼(灯笼可以照亮与它相邻接的点), // 使得所有的边都能被灯笼照亮,其中可能有一些边被两个灯笼 // 照亮,则要求使得所有边都被灯笼照亮所需灯笼的最小值, // 并且,此时边同时被两个灯笼照亮的数目应尽可能的多 // // 思路是 // d[i][0]表示在节点i不放置灯笼所需的灯笼的最小值 // d[i][1]表示在节点i放置灯笼所

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)

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就好 //

uva 1220 - Party at Hali-Bula 【入门树形dp】

题目:uva 1220 - Party at Hali-Bula 题意:一个公司员工要举行聚会,要求任意一个人不能和他的直接上司同时到场,一个员工只有一个支系上司,现在求最多有多少人到场,并且方案是否唯一 分析:分析发现是要求一个树的最大独立集.这里可以用树形dp解决. 定义dp[x][0]:表示在 i 点不选 i 点的以 x 为子树的最大独立集 而dp[x][1] 表示x到场的最大独立集 定义f [x][0]:表示以x为根且x点不选的子树是否唯一 ,f[x][1]表示以x为根且x选的子树是否唯

uva 1484 - Alice and Bob&#39;s Trip(树形dp)

题目链接:uva 1484 - Alice and Bob's Trip 题目大意:Alice和Bob小两口一起出去旅行,他们从0城市出发,Bob喜欢走比较远的路,因为他是个勤奋的好孩子,Alice喜欢走比较近的路,因为她是一个不勤奋的坏孩子,所以有了意见上的分歧,于是乎在出门前他们约法三章,要求说最后的距离值在[l,r]之间,并且由夫妻两轮流做决定,决定说下一个城市去哪里.现在给出n个城市,以及n-1条边,问说在不让Bob媳妇生气的情况下,Bob最远能走多远(不违反约定),如果无法做到不违反约

UVA 12186 Another Crisis(树形DP)

A couple of years ago, a new world wide crisis started, leaving many people with economical problems. Some workers of a particular company are trying to ask for an increase in their salaries. The company has a strict hierarchy, in which each employee