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题--没有上司的舞会 很可惜,这个限制就在那里,它使得我辛苦写 ...
随机推荐
- Cocos2d-x 3.0坐标系详解(转载)
Cocos2d-x 3.0坐标系详解 Cocos2d-x坐标系和OpenGL坐标系相同,都是起源于笛卡尔坐标系. 笛卡尔坐标系 笛卡尔坐标系中定义右手系原点在左下角,x向右,y向上,z向外,OpenG ...
- VI一个终端编辑多个文件的命令
可分两种情况: 在不同窗口中打开多个文件: 如果已经打开一个了一个文件, 则在vi的命令输入状态下输入 :sp 另外一个文件的路径及文件名, 如此就可以在一个窗口打开多个文件了. 可以使用 ...
- 解决DataGridView.DataSource重复赋值而不显示问题
List<Person> list=new List<Person>(); ;i<;i++) { list.Add(new Person(){........}) } d ...
- linux bash shell中case语句的实例
本文介绍下,在bash shell编程中,有关case语句的一个例子,学习下case语句的用法,有需要的朋友参考下. 本文转自:http://www.jbxue.com/article/13377.h ...
- 大量字段表单在PHP便捷处理分享
关于程序开发中的表单批量提交策略很多时候一个表单太多的字段,如何能够高效获取表单字段,也为如何提神开发的效率和统一性? 比如一个系统的某个有26个字段,那么我用表单的名称用26个a到z的字母, 你是选 ...
- IIS日志分析
发现一个强大的图形化IIS日志分析工具——Log Parser Studio,下面分享一个实际操作案例. 1. 安装Log Parser Studio a) 需要先安装Log Parser,下载地址: ...
- 向SDE图层中添加大量数据时,出现ORA-00604以及ORA-01000的解决办法
转自原文 向SDE图层中添加大量数据时,出现ORA-00604以及ORA-01000的解决办法 写了一个小程序,从一个列表中读取坐标串,每个坐标串生成一个IPolygon,然后将这些Polygon添加 ...
- JavaScript自学代码--(四)
//JavaScript Window - 浏览器对象模型 window.document.getElementById("header"); //等价于 document.get ...
- xapian安装
xapian安装:$ su enter your root password # rpm -ivh http://rpm.eprints.org/rpm-eprints-org-key-1-1.noa ...
- PYTHON连MS SQL示例
先要设置WINDOWS的系统DSN的.然后才可以哟. import pyodbc conxn = pyodbc.connect('DSN=BBB; DATABASE=Northwind;UID=AAA ...