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. WordPress 权限方案

    每个主机和主机的情况可能有所差异,如下只是概括性地描述,并不一定适用于所有情况.它只适用于进行“常规设置”的情况(注:比如通过“suexec”方式来进行共享主机的,详情见下方) 通常,所有文件是由您的 ...

  2. [Bzoj4832][Lydsy2017年4月月赛]抵制克苏恩 (期望dp)

    4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 673  Solved: 261[Submit][ ...

  3. ArrayList内部实现原理

    数组在创建的时候长度是固定的,那么就有往ArrayList中不断添加对象的时候,那么ArrayList是如何管理这些数组的? ArrayList内部通过Object[]实现,我们通过分析ArrayLi ...

  4. SQL Server vNext CTP 1.2

    https://msdn.microsoft.com/en-us/library/mt788653.aspx

  5. 基于GDAL的栅格图像空间插值预处理

    转自 基于GDAL的栅格图像空间插值预处理——C语言版 基于GDAL的栅格图像预处理 前言 栅格数据和矢量数据构成空间数据的主要来源,怎样以开源方式读取并处理这些空间数据?目前有多种开源支持包,这里只 ...

  6. 【stl学习笔记】list

    list使用双向链表来管理元素. 与vector.deque的区别: 1.list不支持随机存取,在list中随机遍历任意元素,是很缓慢的行为 2.任何位置上执行元素的安插和移除都非常快,始终是常数时 ...

  7. Guice 学习(八)AOP (面向切面的编程)

    Guice的AOP还是非常弱的.眼下只支持方法级别上的,另外灵活性也不是非常高. 看例如以下演示样例: Guice支持AOP的条件是: 类必须是public或者package (default) 类不 ...

  8. HDU 5303 Delicious Apples (贪心 枚举 好题)

    Delicious Apples Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  9. OSChinaclient源代码学习(2)--缓存的设计

    一.缓存的作用 请求数据的时候,首先进行推断,能否够从缓存中获取数据,假设满足条件,则直接从缓存中获取数据.否则请求新的数据.这样比没有缓存的情况下.每次都要从server请求数据要快,并且.没有网的 ...

  10. 接口测试工具--Fiddler 的使用

    代码部分 Rules -> Customize Rules  打开Fiddler ScriptEditor,这里可以通过修改脚本中某些方法( OnBeforeRequest(oSession: ...