UVa10895 Placing Lampposts
UVa10895 Placing Lampposts
链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34290
【思路】
树上DP+双重优化目标。
本题的特点就是有两个优化目标分别为:在尽量少的结点放灯、在此前提下有被两盏灯照亮的边最多。
首先进行转化:将第二个优化目标转化为在此前提下被一盏灯照亮的边最少。这样两个优化目标就都是求最小值。用一个hash(A,B)将两个新的优化目标AB映射到一个整数,转化为求这个整数的最小值,可以定义hash=A*M+B完成这个功能,M是一个较大数。
树上DP。设d[i][j]表示以i为根的子树且有父节点状态为j时的最优值,注意用j记录父节点状态。有如下转移式:
略。详见代码。
【代码】
#include<iostream>
#include<cstring>
#include<vector>
using namespace std; const int maxn = +;
const int INF=<<;
const int M=; vector<int> G[maxn];
int d[maxn][];
bool vis[maxn][];
int n,m; inline void init() {
for(int i=;i<n;i++) G[i].clear();
memset(vis,false,sizeof(vis));
memset(d,,sizeof(d));
} int dp(int i,int j,int fa) {
if(vis[i][j]) return d[i][j];
vis[i][j]=true;
int &ans=d[i][j]; //无论j都可以在i上放置街灯
ans=M; //放置一个街灯的价值
for(int k=;k<G[i].size();k++) {
int v=G[i][k];
if(v!=fa) {
ans += dp(v,,i);
}
}
if(!j && fa>=) ans++; // if(j || fa<) //根也可以不放
{
int sum=;
for(int k=;k<G[i].size();k++) {
int v=G[i][k];
if(v!=fa) {
sum += dp(v,,i);
}
}
if(fa>=) sum++; //10 //根不算
ans=min(ans,sum); //两种情况取min
} return ans;
} int main() {
ios::sync_with_stdio(false);
int T; cin>>T;
while(T--)
{
cin>>n>>m;
init();
int u,v;
for(int i=;i<m;i++) {
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
}
int ans=;
for(int i=;i<n;i++) if(!vis[i][]) {
ans += dp(i,,-);
}
cout<<ans/M<<" "<<m-ans%M<<" "<<ans%M<<"\n";
}
return ;
}
UVa10895 Placing Lampposts的更多相关文章
- 10_放置街灯(Placing Lampposts,UVa 10859)
问题来源:刘汝佳<算法竞赛入门经典--训练指南> P70 例题30: 问题描述:有给你一个n个点m条边(m<n<=1000)的无向无环图,在尽量少的节点上放灯,使得所有边都被照 ...
- UVA - 10859 Placing Lampposts 放置街灯
Placing Lampposts 传送门:https://vjudge.net/problem/UVA-10859 题目大意:给你一片森林,要求你在一些节点上放上灯,一个点放灯能照亮与之相连的所有的 ...
- UVA 10859 - Placing Lampposts 树形DP、取双优值
Placing Lampposts As a part of the mission ‘Beautification of Dhaka City’, ...
- LightOJ1230 Placing Lampposts(DP)
题目大概说给一个森林求其最小点覆盖数,同时在最小点覆盖条件下输出最多有多少条边被覆盖两次. dp[0/1][u]表示以u为根的子树内的边都被覆盖且u不属于/属于覆盖集所需的最少点数 另外,用cnt[0 ...
- UVa 10859 Placing Lampposts
这种深层递归的题还是要多多体会,只看一遍是不够的 题意:有一个森林,在若干个节点处放一盏灯,灯能照亮与节点邻接的边.要求:符合要求的放置的灯最少为多少,在灯数最少的前提下,一条边同时被两盏灯照亮的边数 ...
- uva 10859 - Placing Lampposts dp
题意: 有n个节点,m条边,无向无环图,求最少点覆盖,并且在同样点数下保证被覆盖两次的变最多 分析: 1.统一化目标,本题需要优化目标有两个,一个最小灯数a,一个最大双覆盖边数b,一大一小,应该归一成 ...
- LightOj 1230 Placing Lampposts(树形DP)
题意:给定一个森林.每个节点上安装一个灯可以覆盖与该节点相连的所有边.选择最少的节点数num覆盖所有的边.在num最小的前提下,合理放置num个灯使得被两个灯覆盖的边最多? 思路:F[i][0]代表没 ...
- UVa 10859 - Placing Lampposts 树形DP 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- UVA10859 Placing Lampposts
我是题面 这道题使我知道了一种很神奇的方法,一定要认真看哦 如果没有被两盏灯同时照亮的边数应尽量大这个限制的话,这就是一道很经典的树形DP题--没有上司的舞会 很可惜,这个限制就在那里,它使得我辛苦写 ...
随机推荐
- Codevs 3990 中国余数定理 2
3990 中国余数定理 2 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 白银 Silver 传送门 题目描述 Description Skytree神犇最近在研究中国博大精深的数学. ...
- 2016.08.06计算几何总结测试day1
T1 bzoj1132[POI2008]TRO 还是太弱了....测试时看到这题直接懵逼,极角排序什么的根本想不起来,只会n^3暴力怎么破......不过竟然有84.....QAQ 正解是n^2log ...
- (hdu)1022 Train Problem I 火车进站问题
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1022 Problem Description As the new term comes, ...
- 关于C++对汉字拼音的处理(2)
对于前面获取字符串汉字全拼音的功能,大家应该有个了解了.现在我又综合广大网友流传的获取字符串汉字拼音首字母的功能进行了整理.介绍如下 这个功能写的稍微有点复杂 使用3个函数解决了获取字符串汉字首拼音串 ...
- C++ 智能指针auto_ptr详解
1. auto_ptr 的设计动机: 函数操作经常依照下列模式进行: 获取一些资源 执行一些动作 释放所获取的资源 那么面对这些资源的释放问题就会出现下面的两种情况: 一开始获得的资源被绑定于局部对象 ...
- 尝试设计LFSR加密器,并用CAP4验证随机性
在CPA4软件中有提供设计LFSR加密器的功能: 输入LFSR的大小,初始密钥,还有反馈密钥. 点击Set Key后点击Show LFSR 观察LFSR,发现初始密钥是1101,转成十六进制是D,反馈 ...
- .NET 中String类功能分类概述
一.比较功能 String.Compare: 成员函数 返回值 功能 String.Compare 小于零.零.大于零. 1.比较两个字符串的大小(按照一定规则) 2.比较两个字符串中子字符串的大小. ...
- BJDP结对编程活动
7月21日参与了 BJDP北京的活动 在北京首次参与能够参与动手编程活动,感觉挺不错的. 本次活动共有三项内容 1. 金锐分享单元测试的Mocking技术,20 mins 2. 伍 ...
- facebook快速登录常见错误:后台设置、域名权限、开发模式、公开、沙盒
开发人员登录地址 : https://developers.facebook.com/?ref=pf 官方登录API文档地址 : https://developers.facebook.com/do ...
- C语言学习笔记——堆和栈——未整理
C语言笔记 栈区 栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出.出入栈是由C语言编译器自动分配 ...