题目

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1800

题意

n(n < 1000)个节点m条边的无向无环无重边图,最小顶点覆盖的同时要尽量让只有一个端点是点亮的边数最少

思路

如刘书:

1. 无向无环图一定是森林,适用树形DP

2. 因为有两个优化目标,所以将两个目标线性组合,设以i为根的树上的顶点覆盖数为x,单点点亮边数为y,由于y < 1000,所以可以这样组合,令M>1000,优化目标为xM + y,此处M不妨取2e3

3. 通常情况下树形DP只考虑当前节点i的点亮状态和i节点到子节点的关系,但这样就需要在x最小的同时,选取一部分子节点亮让y最小,由于子节点的数量可能较多,点亮的方法也有多种,这使得统计单点点亮边数变成了比较复杂的事情。刘书则记录i节点的父节点的点亮状态,这样,统计单点点亮边数时,统计的是i到父亲这一条是不是单点点亮,而不是i到儿子这若干条是不是,更为方便。

4. 令a[i]为当i的父亲节点点亮时,以i为根的子树满足题意所需的最小综合代价,b为不点亮时代价。那么,明显,令suma为子节点a之和,sumb为子节点b之和

统计a[i]时,由于父亲节点已经点亮,i可以选择点亮或者不点亮。令singleEdgeSupp为父节点点亮而i不点亮的代价,当i为根时singleEdgeSupp=0,否则为1.a[i] = min(mina + M, minb + singleEdgeSupp),

统计b[i]时,只能点亮i,b[i] = mina + M + 1

假设这颗树真正的根节点为root,那么答案很明显是a[root],因为可以认为根节点有个虚拟父节点,虚拟父节点是点亮的。

感想

1. 错误地认为边<=1就是叶节点,忽略了根节点只有1个或者没有叶结点的情况。

2. 当只有根节点一个点时,按照Debug上所说的,不需要点灯

代码

  1. #include <algorithm>
  2. #include <cassert>
  3. #include <cmath>
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <iostream>
  7. #include <map>
  8. #include <queue>
  9. #include <set>
  10. #include <string>
  11. #include <tuple>
  12. #define LOCAL_DEBUG
  13. using namespace std;
  14. typedef pair<int, int> MyPair;
  15. int n, m;
  16. const int MAXN = 1e3 + ;
  17. const int M = 2e3;
  18. const int INF = 0x7ffffff;
  19. int edges[MAXN][MAXN];
  20. int edgeCnt[MAXN];
  21. int a[MAXN];//father is lighted up
  22. int b[MAXN];//isn't
  23. bool vis[MAXN];
  24.  
  25. void dfs(int f, int fa) {
  26. vis[f] = true;
  27. if (edgeCnt[f] <= && fa != -) {
  28. a[f] = ;
  29. b[f] = M + ;
  30. }
  31. else {
  32. int singleEdgeSupp = (fa == - ? : );
  33. int suma = ;//light up itself
  34. int sumb = ;//do not light up
  35. for (int i = ; i < edgeCnt[f]; i++) {
  36. int t = edges[f][i];
  37. if (t == fa)continue;
  38. dfs(t, f);
  39. suma += a[t];
  40. sumb += b[t];
  41. }
  42. a[f] = min(suma + M, sumb + singleEdgeSupp);
  43. b[f] = suma + singleEdgeSupp + M;
  44. }
  45. }
  46.  
  47. int main() {
  48. #ifdef LOCAL_DEBUG
  49. freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
  50. freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
  51. #endif // LOCAL_DEBUG
  52. int T;
  53. scanf("%d", &T);
  54. for (int ti = ; ti <= T && scanf("%d%d", &n, &m) == ; ti++) {
  55. memset(edgeCnt, , sizeof(edgeCnt));
  56. memset(vis, , sizeof(vis));
  57. for (int i = ; i < m; i++) {
  58. int f, t;
  59. scanf("%d%d", &f, &t);
  60. edges[f][edgeCnt[f]++] = t;
  61. edges[t][edgeCnt[t]++] = f;
  62. }
  63. int ansNode = ;
  64. int ansSingleEdge = ;
  65. for (int i = ; i < n; i++) {
  66. if (!vis[i]) {
  67. dfs(i, -);
  68. int sta = a[i];
  69. /*if (sta == 0) {
  70. sta = M;
  71. }*/
  72. ansNode += sta / M;
  73. ansSingleEdge += sta % M;
  74. }
  75. }
  76. printf("%d %d %d\n", ansNode, m - ansSingleEdge, ansSingleEdge);
  77.  
  78. }
  79.  
  80. return ;
  81. }

UVa 10859 - Placing Lampposts 树形DP 难度: 2的更多相关文章

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

                              Placing Lampposts As a part of the mission ‘Beautification of Dhaka City’, ...

  2. UVA 10859 Placing Lamppost 树形DP+二目标最优解的求解方案

    题意:给定一个无向,无环,无多重边,要求找出最少的若干点,使得,每条边之中至少有一个点上有街灯.在满足上述条件的时候将还需要满足让两个点被选择的边的数量尽量多. 题解: 对于如何求解最小的节点数目这点 ...

  3. UVaLive 10859 Placing Lampposts (树形DP)

    题意:给定一个无向无环图,要在一些顶点上放灯使得每条边都能被照亮,问灯的最少数,并且被两盏灯照亮边数尽量多. 析:其实就是一个森林,由于是独立的,所以我们可以单独来看每棵树,dp[i][0] 表示不在 ...

  4. UVA - 10859 Placing Lampposts 放置街灯

    Placing Lampposts 传送门:https://vjudge.net/problem/UVA-10859 题目大意:给你一片森林,要求你在一些节点上放上灯,一个点放灯能照亮与之相连的所有的 ...

  5. Uva LA 3902 - Network 树形DP 难度: 0

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  6. uva 10859 - Placing Lampposts dp

    题意: 有n个节点,m条边,无向无环图,求最少点覆盖,并且在同样点数下保证被覆盖两次的变最多 分析: 1.统一化目标,本题需要优化目标有两个,一个最小灯数a,一个最大双覆盖边数b,一大一小,应该归一成 ...

  7. UVa 10859 Placing Lampposts

    这种深层递归的题还是要多多体会,只看一遍是不够的 题意:有一个森林,在若干个节点处放一盏灯,灯能照亮与节点邻接的边.要求:符合要求的放置的灯最少为多少,在灯数最少的前提下,一条边同时被两盏灯照亮的边数 ...

  8. uva10859 Placing Lampposts (树形dp+求两者最小值方法)

    题目链接:点击打开链接 题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮,每盏灯将照亮以它为一个端点的所有边.在灯的总数最小的前提下,被两盏灯同时照亮的边数应尽量大. ...

  9. LightOj 1230 Placing Lampposts(树形DP)

    题意:给定一个森林.每个节点上安装一个灯可以覆盖与该节点相连的所有边.选择最少的节点数num覆盖所有的边.在num最小的前提下,合理放置num个灯使得被两个灯覆盖的边最多? 思路:F[i][0]代表没 ...

随机推荐

  1. nRF52832-PPI部分学习

    PPI部分学习思维导图 PPI原理 1.1PPI简介 PPI实现的就是通过初始化配置,将不同外设的事件和任务连接起来,让事件自动去触发任务的功能,PPI有多个通道, 每个通道包含一个EEP和TEP,使 ...

  2. Python2 - MySQL适配器 MySQLdb

    本文实例讲述了python中MySQLdb模块用法.分享给大家供大家参考.具体用法分析如下: MySQLdb其实有点像php或asp中连接数据库的一个模式了,只是MySQLdb是针对mysql连接了接 ...

  3. 雷林鹏分享:jQuery EasyUI 扩展

    jQuery EasyUI 扩展 Portal(制作图表.列表.球形图等) 数据网格视图(DataGrid View) 可编辑的数据网格(Editable DataGrid) 可编辑的树(Editab ...

  4. 开发自己的R包(转)

    R不必说,数据统计分析可视化的必备语言,R包开发的门槛比较低,所以现在随便一篇文章都会发表一个自己的R包,这样有好处(各种需求早有人帮你解决了)也有坏处(R包太多,混乱,新手上手较难).作为生信工程师 ...

  5. 看到篇博文,用python pandas改写了下

    看到篇博文,https://blog.csdn.net/young2415/article/details/82795688 需求是需要统计部门礼品数量,自己简单绘制了个表格,如下: 大意是,每个部门 ...

  6. BGP - 5,BGP属性

    metric,自己决定去哪个EBGP邻居 local-pre,影响AS内部IBGP邻居的路由决策 med,影响AS外部EBGP邻居的路由决策   1,BGP属性     公认传递(well-known ...

  7. canvas手机端绘图解决方案

    解决方案js:https://pan.baidu.com/s/1jIys2aU 我们使用canvas通常会遇到一个问题就是坐标系的问题,如果按象限来说,一般canvas是在第四象限,但是我们通常都喜欢 ...

  8. Hadoop/HBase Capacity Planning

    http://blog.cloudera.com/blog/2010/08/hadoophbase-capacity-planning/

  9. jenkins+maven+git+tomcat+salt自动构建

    jenkins 安装步骤 环境: centos7,jdk1.8.0,jenkins2.165,maven3.5.2 一. 安装配置java环境   JDK1.8下载地址:http://www.orac ...

  10. PHP流程控制笔记

    一.运算符(Operator) 1.运算符 2.运算符分类   (1)按功能分   (2)按操作数个数分 3.按功能分   (1)算术运算符   (2)递增递减   (3)字符运算符   (4)赋值运 ...