这种深层递归的题还是要多多体会,只看一遍是不够的

题意:有一个森林,在若干个节点处放一盏灯,灯能照亮与节点邻接的边。要求:符合要求的放置的灯最少为多少,在灯数最少的前提下,一条边同时被两盏灯照亮的边数最多是多少。

因为边数为m,所以被两盏灯照亮的边数最多就等价于被一盏灯照亮的边数最少

因为题目中要求两个最优解,将x = Ma + c 作为最小化的目标,其中a为灯数,c为被一盏灯照亮的边数,M则是一个比较大的值,到底有多大呢?M要比c的理论上的最大值与最小值之差还要大。这样在比较x1 和 x1时,如果a1 > a2,则x1一定>x2,这样就的好处就是将两个变量的最优解变成了一个变量的最优解,而且保证了灯数最少的前提下再求边数的最优解。

书上的两种决策说的很清楚了,我不就再啰嗦了。

我感觉我有点消化不良,认真体会,认真体会。。

 //#define LOCAL
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = + ;
vector<int> adj[maxn];
int vis[maxn][], d[maxn][], n, m; int dp(int i, int j, int f)
{
if(vis[i][j]) return d[i][j];
vis[i][j] = ;
int& ans = d[i][j];
//放灯总是没有问题的
ans = ;
for(int k = ; k < adj[i].size(); ++k)
if(adj[i][k] != f)
ans += dp(adj[i][k], , i);
if(f >= && j == ) ++ans;
//考虑没放灯时的情况
if(f < || j == )
{
int sum = ;
for(int k = ; k < adj[i].size(); ++k)
if(adj[i][k] != f)
sum += dp(adj[i][k], , i);
if(f >= ) ++sum;
ans = min(ans, sum);
}
return ans;
} int main(void)
{
#ifdef LOCAL
freopen("10859in.txt", "r", stdin);
#endif int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(int i = ; i < n; ++i) adj[i].clear();
for(int i = ; i < m; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
adj[a].push_back(b);
adj[b].push_back(a);
}
memset(vis, , sizeof(vis));
int ans = ;
for(int i = ; i < n; ++i)
if(!vis[i][])
ans += dp(i, , -);
printf("%d %d %d\n", ans/, m-(ans%), ans%);
}
return ;
}

代码君

UVa 10859 Placing Lampposts的更多相关文章

  1. UVA - 10859 Placing Lampposts 放置街灯

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

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

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

  3. UVa 10859 - Placing Lampposts 树形DP 难度: 2

    题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...

  4. uva 10859 - Placing Lampposts dp

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

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

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

  6. UVaLive 10859 Placing Lampposts (树形DP)

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

  7. 10_放置街灯(Placing Lampposts,UVa 10859)

    问题来源:刘汝佳<算法竞赛入门经典--训练指南> P70 例题30: 问题描述:有给你一个n个点m条边(m<n<=1000)的无向无环图,在尽量少的节点上放灯,使得所有边都被照 ...

  8. UVa10895 Placing Lampposts

    UVa10895 Placing Lampposts 链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34290 [思路] ...

  9. LightOJ1230 Placing Lampposts(DP)

    题目大概说给一个森林求其最小点覆盖数,同时在最小点覆盖条件下输出最多有多少条边被覆盖两次. dp[0/1][u]表示以u为根的子树内的边都被覆盖且u不属于/属于覆盖集所需的最少点数 另外,用cnt[0 ...

随机推荐

  1. Tomcat自动启动脚本

    Tomcat自动启动脚本#!/bin/bash # chkconfig: 2345 10 90 # description: Starts and Stops the Tomcat daemon. T ...

  2. spring mvc Controller与jquery Form表单提交代码demo

    1.JSP表单 <% String basePath = request.getScheme() + "://" + request.getServerName() +&qu ...

  3. 正确使用HTML title属性

    如果你想对使用手机,平板电脑和辅助技术的用户隐藏某些内容,而只对键盘用户显示,那么请使用title属性. 细节 HTML的title属性本身有问题.之所以有问题是因为它在一些重要的方面表现的不够好,尽 ...

  4. c# 发送消息到Email

    /// <summary>        /// 发送消息到Email        /// </summary>        /// <param name=&quo ...

  5. WCF传输Dataset大数据量 -压缩

    由于WCF不能传输DataTable(不能序列化),所以更多项目中都会使用DataSet作为查询集合的首选返回类型,但是由于DataSet会生成很多的状态信息等,所以DataSet体积也会变大,有几种 ...

  6. Spark源码分析(一)-Standalone启动过程

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3858065.html 为了更深入的了解spark,现开始对spark源码进行分析,本系列文章以spark ...

  7. hadoop jobhistory解析工具汇总

    1. White Elephant是LinkedIn开源的一套Hadoop 作业日志收集器和展示器,使用mapreduce作业解析jobhistory日志,得到每个用户使用的资源情况,并通过网页展示. ...

  8. Android 音乐播放器之--错误状态下调用导致的异常

    MediaPlayer必须在合适的状态下调用合适的方法,否则会出现异常,下面列出常见错误信息和说明: 1.E/MediaPlayer(11310): stop called in state 1 调用 ...

  9. ruby脚本,随机生成复杂密码

    简单版本: base_char = (32..126).map{|i|i.chr} - ["'",'"'," ", "`",&qu ...

  10. angular todo

    <!DOCTYPE HTML> <html lang="en-US" ng-app> <head> <meta charset=" ...