前面也做了一道很像的题,那道题只要求放置的数目最少,要求覆盖的是点。在这题中,要求覆盖的是边,不但要求放着的数目最少,更要求覆盖两次的边最多。因此贪心法不再适用,最少要多少个点可以贪心求出,但是同时要求覆盖两次的边要最多却不是贪心法能够解决的,无论如何都是逃不过动态规划的。所以一开始用贪心做,做到最后发现方法是错的。看了大白书才开始用动态规划。

大白书上的方法好奇怪,dp[i][j]代表i节点的父亲节点是否放灯。好难理解。我用dp[i][j]代表i节点是否放灯思路十分清晰,很快就AC了。看了好久书才理解大白书上的做法,感觉不是很好。

大白书上最值得学习的地方就是如何定义动态规划的值。

本题的优化目标有两个,一个是要求灯数a应尽量少,另一个是要求被两盏灯同时照亮的边数b应尽量大。如果灯数尽量少,那么就不会出现一条边被照亮3次的低效情况,因此总边数=被照亮1次的边数+被照亮2次的边数。即M=b+c。我们要求b尽量大,那么要求c尽量小即可。这样就把两个优化目标都转化成了尽量小。题目要求在a尽量小的前提下c尽量小,有个技巧是将二者组合成一个量aM+c,M是一个比(c的最大理论值-c的最小理论值)还要大的数,这样当aM+c最小时,一定是先保证了a最小,再保证c最小。在本题中M取2000。

我的方法:

若u不放灯,那么值就是所有(子节点v放灯的值+1)的和。+1是因为uv之间只被照亮1次。

若u放灯,那么所以子节点爱放不放,如果不放,就要+1,然后取最小值求和就好了。

设根为root,答案就是min(dp[root][0],dp[root][1])。

思路又清晰,编码又简单,自己觉得比书上好多了。

我的方法

#include<bits/stdc++.h>
#define maxn 1010
#define MAX 2000
using namespace std;int N,M;
vector<int>MAP[maxn];
int dp[maxn][2];
bool vis[maxn];void dfs(int u,int f)
{vis[u]=true;dp[u][0]=0;dp[u][1]=MAX;for(unsigned int i=0;i<MAP[u].size();i++){int v=MAP[u][i];if(v==f) continue;dfs(v,u);dp[u][0]+=dp[v][1]+1;dp[u][1]+=min(dp[v][0]+1,dp[v][1]);}
}int main()
{int T;scanf("%d",&T);while(T--){scanf("%d %d",&N,&M);for(int i=0;i<N;i++){MAP[i].clear();vis[i]=0;}int u,v;for(int i=0;i<M;i++){scanf("%d %d",&u,&v);MAP[u].push_back(v);MAP[v].push_back(u);}int a,b,c;a=b=c=0;for(int i=0;i<N;i++){if(!vis[i]){dfs(i,-1);int ans=min(dp[i][0],dp[i][1]);a+=ans/MAX;c+=ans%MAX;}}b=M-c;printf("%d %d %d\n",a,b,c);}return 0;
}

书上的方法

#include<bits/stdc++.h>
#define maxn 1010
#define MAX 2000
using namespace std;int N,M;
vector<int>MAP[maxn];
bool vis[maxn];
int dp[maxn][2];void dfs(int u,int f)
{vis[u]=true;int jc1,jc2;jc1=jc2=0;for(unsigned int i=0;i<MAP[u].size();i++){int v=MAP[u][i];if(v==f) continue;dfs(v,u);jc1+=dp[v][0];jc2+=dp[v][1];}jc2+=MAX;dp[u][0]=dp[u][1]=jc2;if(f!=-1) dp[u][0]++;if(f==-1){dp[u][0]=min(dp[u][0],jc1);dp[u][1]=min(dp[u][1],jc1);}else dp[u][1]=min(dp[u][1],jc1+1);}int main()
{int T;scanf("%d",&T);while(T--){scanf("%d %d",&N,&M);for(int i=0;i<N;i++){MAP[i].clear();vis[i]=0;}int u,v;for(int i=0;i<M;i++){scanf("%d %d",&u,&v);MAP[u].push_back(v);MAP[v].push_back(u);}int a,b,c;a=b=c=0;for(int i=0;i<N;i++){if(!vis[i]){dfs(i,-1);int ans=dp[i][0];a+=ans/MAX;c+=ans%MAX;}}b=M-c;printf("%d %d %d\n",a,b,c);}return 0;
}

树形DP(放置街灯,uva 10859)相关推荐

  1. [动态规划] 放置街灯 Uva 10859 - Placing Lampposts

    [动态规划] 放置街灯 Uva 10859 - Placing Lampposts 英文题目: As a part of the mission �Beautification of Dhaka Ci ...

  2. uva 10859 放置街灯树形dp

    首先,本题的优化目标有两个:放置的街灯a应该尽量少:被两灯同时照亮的边数b应该尽量大.为了统一起见,我们把后者替换为:恰好被一盏灯照亮的边数c应该尽量小,然后改用x = Ma+c作为优化目标,其中一个 ...

  3. uva10859放置街灯(树形dp)

    例题 30 放置街灯( Placing Lampposts, UVa 10859 ) 给你一个 n 个点 m 条边的无向无环图, 在尽量少的结点上放灯, 使得 所有边都被照亮. 每盏灯将照亮以它为一个 ...

  4. uva 10859 放置街灯--Placing Lampposts

    uva 10859 - Placing Lampposts(树形dp ###两个别人家的代码,没有注释看了很久 ###所以自己改写了一遍,附注释 https://blog.csdn.net/keshu ...

  5. Placing Lampposts ,UVa 10859 树形dp

    UVa 10859 日常刷白书,第三次刷dp刷到这题,竟然还是不会写..... 这个题给定n个点m条边的无向无环图,有至多1000个节点,每个节点有两个状态,可以放灯或者不放灯,要求放最少的灯使得所有 ...

  6. UVA10859 放置街灯 Placing Lampposts(树状DP)

    UVA10859 放置街灯 Placing Lampposts(树状DP) 这道题有两种解决方法,因为原图保证无重边无环无自环, 所以原图一定是一颗树(或森林).,都是树状DP,但是实现的过程大同小异 ...

  7. uva 1218 Perfect Service 树形dp

    // uva 1218 Perfect Service 树形dp // // 解题思路: // // d[u][0]表示节点本身是服务器 // d[u][1]表示节点的父节点是服务器 // d[u][ ...

  8. UVA - 1218 Perfect Service(树形dp)

    题目链接:UVA - 1218 Perfect Service 题意 有n台电脑,互相以无根树的方式连接,现要将其中一部分电脑作为服务器,且要求每台电脑必须连接且只能连接一台服务器(不包括作为服务器的 ...

  9. Party at Hali-Bula UVA - 1220(树形dp)

    题目链接:传送门 思路:求最多参与人数是树形dp的入门题,和没有上司的舞会是一个题目,但是这个题目还要求答案是否唯一.我们开设一个标记数组vis,标记就可以了.具体解释看代码: #include< ...

  10. 紫书动规 例题9-13 UVA - 1220 Party at Hali-Bula 树形dp

    题目链接: https://vjudge.net/problem/UVA-1220 题意: 题解: 树形dp: 树的最大独立集问题 d[u][0]:=不选u能得到的最大人数 d[u][0]=sum{m ...

最新文章

  1. 数字图像基础(二进制图像、灰度图像、RGB图像、索引图像和多帧图像)
  2. python创建软连接_centos7 上 创建软连接 ln -s
  3. python清洗数据用什么包_格式化和清洗数据的Python工具包
  4. Android.mk中添加宏定义
  5. android progressdialog 样式,android之修改系统自带ProgressDialog样式
  6. [转载] 算法竞赛中的JAVA使用笔记
  7. winpcap基本原理及常见应用_碳十四测年的基本原理和常见应用谬误
  8. Linux下的防火墙管理(包含图形和命令、伪装和转发)
  9. 获得N^2个往返接力数字表格的算法
  10. html5 复制到剪贴板 兼容,js/jQuery实现复制到剪贴板功能,兼容所有浏览器
  11. spring定时任务详解
  12. UI设计师需要熟记的45个快捷键Windows、Mac
  13. dnf服务器不维修,dnf无法修理装备
  14. 强大的网页数据库管理工具Adminer
  15. H5页面唤起指定app或跳转到应用市场
  16. webgis、gis学习技巧总结
  17. 过冲(overshoot)、下冲(Undershoot)的量化标准与评估实例
  18. Cascade R-CNN: Delving into High Quality Object Detection(个人学习笔记)
  19. 像诗人一样睿智,像天才一样疯狂
  20. 图像、图形、图片文件格式

热门文章

  1. 关于 SAP ABAP 报表的多语言显示问题试读版
  2. GlobalSign证书有哪些基本好处
  3. 计算时间复杂度--(简单版)
  4. EVE模拟器关联CRT与Wireshark
  5. HDOJ 3911 线段树
  6. 网络最大流中一般增广路算法(标号法)
  7. 交换机putty怎么调试_【技术】如何登陆交换机进行命令配置?常用的交换机组网模拟器有哪些?...
  8. zTree单击展开节点
  9. dell10代cpu装linux,戴尔10代cpu装win7系统及bios设置|戴尔十代cpu台式机装win7
  10. 有效学习的6个方法学习方法