Placing Lampposts

传送门:https://vjudge.net/problem/UVA-10859

题目大意:给你一片森林,要求你在一些节点上放上灯,一个点放灯能照亮与之相连的所有的边。问你最小化防止的灯数,在灯数相同的条件下,最大化两个点都有灯的边数。
题解:

  首先有一个套路,也是做了此题才知道的,很神奇啊。最小化灯的数量,我们设灯数为V1,把“最大化两个点都有灯的边数”转化为“最下化只有一个点有灯的边数”,设为V2,那么我们设Val=Eps*V1+V2。这样只要DP一个值就可以了。Eps设成一个足够大的值,保证Eps>sum{V2}。此题姑且设为2000。
  然后我们就可以DP了。树上求解最优解,此题为森林,转化为每棵树的答案相加就可以了。那么怎么DP呢?
  设状态DP[i]代表i节点与它的子树以及连向父亲的那一条边的最小的Val。每一个节点有放灯与不放灯两种状态,但是我们发现,父亲放不放灯会影响儿子放不放灯,那么我们再加上一维的状态:dp[i][0/1]代表代表i节点与它的子树以及连向父亲的那一条边的最小的Val,j=1为父亲放灯,j=0代表父亲不放灯。
考虑两种方案:
1.  i放灯:i放灯的话,对于其他的没有什么要求,所以dp[i][j]+=dp[son][1],dp[i][j]+=Eps。如果当前j==0,并且不是根节点,那么dp[i][j]++,因为到父亲的那一条边只有1个灯。
2.  i不放灯:i不放灯,转移就有限制条件了,必须父亲放灯,或者i为根节点,dp[i][1]+=dp[son][0],如果i不是根节点,那么还要++,同样的因为到父亲的那一条边只有1个灯。
  然后一边dfs一边DP就可以了。注意状态转移是错综复杂的,并不是单一的0->1或0->0,具体顺序见代码。
  条件1可以更新j=1和0的情况;条件2只能更新j=1的情况,但是在根节点也可以更新j=0的情况。

 #include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define RG register
#define LL long long
#define fre(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
const int MAXN=,Eps=;
int n,num,m,Case,ans;
int dp[MAXN][];
int head[MAXN],to[MAXN],Next[MAXN];
bool vis[MAXN];
void dfs(int u,int fa)
{
vis[u]=;
int sum1=,sum2=Eps;
for(int i=head[u];i;i=Next[i])
{
int v=to[i];
if(v==fa)continue;
dfs(v,u);
sum1+=dp[v][];//不放灯
sum2+=dp[v][];//放灯
}
if(fa!=)sum1++;
dp[u][]=sum1;
dp[u][]=min(dp[u][],sum2);//与放灯的再比较一下。
dp[u][]=sum2;
if(fa!=) dp[u][]++;
if(fa==)
dp[u][]=min(dp[u][],sum1);
}
void add(int f,int t)
{
Next[++num]=head[f];
to[num]=t;
head[f]=num;
}
int main()
{
scanf("%d",&Case);
while(Case--)
{
scanf("%d%d",&n,&m);
num=;
memset(head,,sizeof head);
memset(vis,,sizeof vis);
memset(dp,,sizeof dp);
for(int i=,a,b;i<=m;i++)
{
scanf("%d%d",&a,&b);
a++,b++;
add(a,b); add(b,a);
}
ans=;
for(int i=;i<=n;i++)
if(!vis[i])
{
dfs(i,);
ans+=min(dp[i][],dp[i][]);
}
printf("%d %d %d\n",ans/Eps,m-ans%Eps,ans%Eps);
}
return ;
}

UVA - 10859 Placing Lampposts 放置街灯的更多相关文章

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

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

  2. UVa 10859 Placing Lampposts

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

  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. UVa10859 放置街灯

    Placing Lampposts As a part of the mission �Beautification of Dhaka City�, the government has decide ...

随机推荐

  1. Knockout.js用jquery的val设置值不更新

    用如下方法,加上change() .val("blah").change()

  2. 【APUE】关于信号的一些常用函数

    kill和raise函数 #include <signal.h> int kill(pid_t pid,int signo); int raise(int signo);//两个函数返回值 ...

  3. Linux 命令 sudo

    sudo 这个命令. 是为了 让 普通用户 ,也能够以root的身份来运行 操作, 而这些普通用户 又不须要知道root的password. 在 sudo 运行命令的时候. 仅仅须要 输入自己的pas ...

  4. form怎样正确post文件

    form在HTML中,是用于收集用户输入的,基本全部浏览器都支持form.给form加入method属性.就能实现将用户在form内控件输入的信息POST到制定地址.或发送GET请求. 写了以下一段代 ...

  5. &lt;Android&gt;greenrobot-EventBus,guava-Event Bus的异步实现

    刚開始是从otto入手,可是otto不支持异步运行.所以后来才開始研究了Event Bus.关于Event Bus,先前搜索的时候,看到网上的实例,非常碎,并且非常多都是一样的内容,代码看下来基本上是 ...

  6. 【剑指Offer】俯视50题之21 - 30题

    面试题21包括min函数的栈  面试题22栈的压入.弹出序列  面试题23从上往下打印二叉树  面试题24二叉搜索树的后序遍历序列  面试题25二叉树中和为某一值的路径  面试题26复杂链表的复制  ...

  7. MySQL基础笔记(一) SQL简介+数据类型

    MySQL是一个关系型数据库管理系统(RDBMS),它是当前最流行的 RDBMS 之一.MySQL分为社区版和企业版,由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发 ...

  8. Redis5.0之Stream案例应用解读

    非常高兴有机会和大家在这里交流Redis5.0之Stream应用.今天的分享更多的是一个抛砖引玉,欢迎大家提出更多关于Redis的思考. 首先,我们来个假设,这里有个杯子,这个杯子是去年我老婆送的,送 ...

  9. 2 Angular 2 的核心概念

    一.组件(Components): 组件是构成 Angular 应用的基础和核心,它是一个模板的控制类,用于处理应用和逻辑页面的视图部分.组件知道如何渲染自己及配置依赖注入,并通过一些由属性和方法组成 ...

  10. CodeForces 300C Beautiful Numbers(乘法逆元/费马小定理+组合数公式+高速幂)

    C. Beautiful Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standar ...