传送门

Description

给定一个\(n\)个点\(m\)条边的无向无环图,选择尽量少的节点,使得所有边都至少有一个顶点被选择。在这个基础上,要求有两个顶点被选择的边数尽可能大

Input

多组数据。第一行是数据组数\(T\)。

以下\(T\)组,每组包括:

第一行两个整数\(n\),\(m\)。

下面\(m\)行,每行两个整数\(u\),\(v\)。代表一条边。

Output

对于每组数据输出一行,包括三个用空格隔开的整数,分别是:

最小的灯的个数,两个顶点都被选择的边数,一个顶点被选择的边数

Sample Input

2
4 3
0 1
1 2
2 3
5 4
0 1
0 2
0 3
0 4

Sample Output

2 1 2
1 0 4

Hint

\(For~All:\)

\(m~<~n~\leq~1000\)

Solution

考虑无向无环图本质上是个森林,各个树互不影响。于是下面只研究单棵树的情况。

考虑这个题的优化目标有两个,分别是要求点数尽可能少,还有两个顶点被选择的边尽可能多。为了统一取max和min,我们将目标二改为有且仅有一个顶点被选择的边尽可能少。

对于同时最小化两个目标,而且在第一个目标最小的时候需要最小化第二个目标的的时候,可以设第一个目标的值是\(x_1\),第二个目标的值是\(x_2\)。目标为最小化\(ans=x_1~\times~K+x_2\),其中满足\(K~>~max_{x_2}\)。

于是对于本题就可以套这种方法。由于\(n~\leq~1000\),所以不妨设\(K=2000\)。设\(f_{i,0/1}\)为以\(i\)为根的子树合法,且点\(i\)不选/选的答案。

方程显然:

\[f_{i,0}~=~\sum\{f_{to,1}+1\}
\]

\[f_{i,1}~=~\sum~min~\{f_{to,1}~,~f_{to,0}+1\}+k
\]

于是就没了

Code

#include<cstdio>
#include<cstring>
#define rg register
#define ci const int
#define cl const long long int typedef long long int ll; namespace IO {
char buf[90];
} template<typename T>
inline void qr(T &x) {
char ch=getchar(),lst=' ';
while(ch>'9'||ch<'0') lst=ch,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
if(lst=='-') x=-x;
} template<typename T>
inline void write(T x,const char aft,const bool pt) {
if(x<0) x=-x,putchar('-');
int top=0;
do {
IO::buf[++top]=x%10+'0';
x/=10;
} while(x);
while(top) putchar(IO::buf[top--]);
if(pt) putchar(aft);
} template<typename T>
inline T mmax(const T a,const T b) {return a > b ? a : b;}
template<typename T>
inline T mmin(const T a,const T b) {return a < b ? a : b;}
template<typename T>
inline T mabs(const T a) {return a < 0 ? -a : a;} template<typename T>
inline void mswap(T &a,T &b) {
T temp=a;a=b;b=temp;
} const int st = 2000;
const int maxn = 1010;
const int maxm = 2010; struct Edge {
int to,nxt;
};
Edge edge[maxm];int hd[maxn],ecnt;
inline void cont(ci from,ci to) {
Edge &e=edge[++ecnt];
e.to=to;e.nxt=hd[from];hd[from]=ecnt;
} int n,m;
int frog[maxn][2];
bool vis[maxn]; void clear();
void reading();
void dfs(ci,ci); int main() {
rg int t=0;qr(t);
while(t--) {
clear();
qr(n);qr(m);
rg int _ans=0;
reading();
for(rg int i=1;i<=n;++i) if(!vis[i]) {
dfs(i,0);_ans+=mmin(frog[i][0],frog[i][1]);
}
rg int tk=_ans%st;
write(_ans/st,' ',true);write(m-tk,' ',true);write(tk,'\n',true);
}
return 0;
} void clear() {
n=m=ecnt=0;
memset(hd,0,sizeof hd);
memset(vis,0,sizeof vis);
memset(edge,0,sizeof edge);
memset(frog,0,sizeof frog);
} void reading() {
rg int a,b;
for(rg int i=1;i<=m;++i) {
a=b=0;qr(a);qr(b);++a,++b;
cont(a,b);cont(b,a);
}
} void dfs(ci u,ci fa) {
vis[u]=true;
frog[u][1]=st;
for(rg int i=hd[u];i;i=edge[i].nxt) {
int &to=edge[i].to;
if(to == fa) continue;
dfs(to,u);
frog[u][0]+=frog[to][1]+1;
frog[u][1]+=mmin(frog[to][1],frog[to][0]+1);
}
}

Summary

对于同时最小化两个目标,而且在第一个目标最小的时候需要最小化第二个目标的的时候,可以设第一个目标的值是\(x_1\),第二个目标的值是\(x_2\)。目标为最小化\(ans=x_1~\times~K+x_2\),其中满足\(K~>~max_{x_2}\)。

【树形DP】【UVA10859】 Placing Lampposts的更多相关文章

  1. UVA10859 Placing Lampposts

    我是题面 这道题使我知道了一种很神奇的方法,一定要认真看哦 如果没有被两盏灯同时照亮的边数应尽量大这个限制的话,这就是一道很经典的树形DP题--没有上司的舞会 很可惜,这个限制就在那里,它使得我辛苦写 ...

  2. uva10859 Placing Lampposts (树形dp+求两者最小值方法)

    题目链接:点击打开链接 题意:给你一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都被照亮,每盏灯将照亮以它为一个端点的所有边.在灯的总数最小的前提下,被两盏灯同时照亮的边数应尽量大. ...

  3. 再谈树形dp

    上次说了说树形dp的入门 那么这次该来一点有难度的题目了: UVA10859 Placing Lampposts 给定一个n个点m条边的无向无环图,在尽量少的节点上放灯,使得所有边都与灯相邻(被灯照亮 ...

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

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

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

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

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

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

  7. 「算法笔记」树形 DP

    一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...

  8. UVA - 10859 Placing Lampposts 放置街灯

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

  9. 树形DP入门学习

    这里是学习韦神的6道入门树形dp进行入门,本来应放在day12&&13里,但感觉这个应该单独放出来好点. 这里大部分题目都是参考的韦神的思想. A - Anniversary part ...

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

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

随机推荐

  1. HTTP基本定义

    一.网络的简单定义: 1.http:是www服务器传输超文本向本地浏览器的传输协议.(应用层) 2.IP:是计算机之间相互识别通信的机制.(网络层) 3.TCP:是应用层通信之间通信.(传输层) IP ...

  2. 第三模块:面向对象&网络编程基础 第3章 选课系统作业讲解

    01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课系统作业讲解4 01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课 ...

  3. IntelliJ IDEA 新建项目

    一 新建一个Java项目 二 新建一个Web项目 三 新建一个Maven项目 四 web.xml常见版本 <?xml version="1.0" encoding=" ...

  4. 使用maven构建web项目(简易版)

    在eclipse中使用maven开发一个web项目 第一步:安装maven:在Windows上安装Maven 中间省略很多步骤....(包括关于eclipse中配置maven) 第二步:不用懂任何ma ...

  5. lintcode12 带最小值操作的栈

    实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. 建一个栈helpStack,用来存放从 ...

  6. 《Effective C++》读书笔记 条款02 尽量以const,enum,inline替换#define

    Effective C++在此条款中总结出两个结论 1.对于单纯常量,最好以const对象或enum替换#define 2.对于形似函数的宏,最好改用inline函数替换#define 接下来我们进行 ...

  7. Y460蓝牙键盘无法连接问题解决

    mac坏了,无法启动,一直没时间去修理. 近期把大学的时候用的笔记本又翻了出来,小Y,经典的“娱乐本” Y460. Y460上之前被自己各种重装系统,反复从windows到双系统,再到linux之间来 ...

  8. 你真的了解JAVA里的String么

    Java中String类细节问题 (考察点Java内存分配问题) 1. String str1 = "abc";   System.out.println(str1 == &quo ...

  9. Martin Fowler关于IOC和DI的文章(中文版)

    IoC容器和Dependency Injection模式 Martin Fowler 编者语:最近研究IoC,在网上搜索到很多网页推荐阅读Martin Fowler的一片名叫Inversion of  ...

  10. Django学习笔记---第一天

    Django学习笔记 1.Django的安装 //如果不指定版本号,默认安装最新版 pip3 install django==1.11.8 关于Django的版本和python的版本依赖关系,请看下图 ...