UVA 10859 Placing Lampposts(树形DP)

题意:

给定一张有向无环图,每个节点视作一个路口,每条边视作路,要求挑选一些节点放置路灯,使每条路都能被路灯照到,且使用的路灯数最少,如若存在使用相同路灯数的情况,则使得能被两盏路灯照到的路的数量尽量多。

解题:

可以将此问题提炼一下,就是使用最少的路灯照亮所有的路,使得被两盏路灯照亮的路尽量多,也就是使被一盏路灯照亮的路尽量少。那么问题可以转换为,使用最少x盏路灯,使得最少为y条路被一盏路灯照亮。那么问题就抽象为,W=k*x+y(其中k>y)使得W尽量小。因为,k>y,也就保障了x为首要条件。dp[i][0]表示第i个节点不选,dp[i][1]表示第i个节点选的最小值。当一个节点其父节点为不选时,那么它必选,因为若不选,那么他们之间的路就无法照亮了,倘若父节点选了,那么该节点可选可不选,取两者间的小者,若相同,那么则选选的,因为这样被两盏灯照亮的路径数多。

代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <map>
#define inf 0x3f3f3f3f
using namespace std;
int n,m,head[1010],cnt,nxt[2020],dp[1010][2];
bool vis[1010];
struct edge
{
	int fm,to;
}store[2020];
int min(int a,int b)
{
	return a<b?a:b;
}
void add_edge(int x,int y)
{
	nxt[cnt]=head[x];
	head[x]=cnt;
	store[cnt].fm=x;
	store[cnt].to=y;
	cnt++;
	nxt[cnt]=head[y];
	head[y]=cnt;
	store[cnt].fm=y;
	store[cnt].to=x;
	cnt++;
}
void dfs(int x)
{
	int to;
	vis[x]=1;
  	dp[x][0]=0;
  	dp[x][1]=1010;
  	for(int i=head[x];~i;i=nxt[i])
  	{
	  	to=store[i].to;
	  	if(vis[to])continue;
        dfs(to);
        dp[x][0]+=dp[to][1]+1;//一盏灯照亮
		if(dp[to][0]<dp[to][1])
			dp[x][1]+=dp[to][0]+1; //单盏灯亮的情况
		else
		    dp[x][1]+=dp[to][1];  //相等的情况下,选择不加1
    }
}
int main()
{
    int t,a,b,ans;
	scanf("%d",&t);
	while(t--)
	{
		cnt=ans=0;
		scanf("%d%d",&n,&m);
		memset(head,-1,sizeof(head));
		memset(vis,0,sizeof(vis));
		memset(nxt,-1,sizeof(nxt));
		for(int i=0;i<m;i++)
		{
			scanf("%d%d",&a,&b);
			add_edge(a,b);
		}
		for(int i=0;i<n;i++)
		{
			if(!vis[i])
			{
			  dfs(i);
	          ans+=min(dp[i][0],dp[i][1]);
			}
		}
		printf("%d %d %d\n",ans/1010,m-ans%1010,ans%1010);
	}
	return 0;
}
时间: 2024-11-08 13:45:49

UVA 10859 Placing Lampposts(树形DP)的相关文章

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

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

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

uva 10859 Placing Lampposts,树形dp

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

UVA 10859 Placing Lampposts(树DP)

题意:给一个n个顶点m条边的无向无环图,在尽量少的结点上放灯,使得所有边都被照亮.每盏灯将照亮以它为一个端点的所有边.在灯的总数最小的前提下,被两盏灯同时照亮的变数应该尽量大. 思路:无向无环图就是"森林",常用树形dp,本题要优化的目标有两个,放置的灯数a应尽量少,被两盏灯同时照亮的边数b应尽量大,为了统一,我们把b替换成"恰好被一盏灯照亮的边数c尽量小".然后设x=Ma+c为最终的优化目标,M是一个很大的正整数.当x取最小值的时候,x/M就是a的最小值,x%M就

UVA - 10859 Placing Lampposts

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

LightOj 1230 Placing Lampposts(树形DP)

题意:给定一个森林.每个节点上安装一个灯可以覆盖与该节点相连的所有边.选择最少的节点数num覆盖所有的边.在num最小的前提下,合理放置num个灯使得被两个灯覆盖的边最多? 思路:F[i][0]代表没放灯,F[i][1]代表放了灯,G[i]类似. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6

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 - 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)