题意:给定一个图,节点可以放灯,要求用最少的灯覆盖所有的边(每盏灯能覆盖该节点邻接的边),满足条件的同时求该前提下尽量多的被两盏灯照亮的边数

条件二转化为求尽量少的被一盏灯照亮的边数,两个条件都是求min,我们需要构造一个条件一取决定性作用的式子,

令\(f(a,b)=Ma+b\),其中\(a\)为条件一的最优解,\(M\)为一个足够大的数,以至于\(b\)的最大值都小于\(M\)(更精确的应该是\(M>b_{max}-a_{min}\)),那么\(b\)为满足\(a\)前提下的最优解,所以我们就是在图上DP求解这条式子的min,两个系数分别对应不同的解

有一些实现上的细节需要注意,dp方程应该设\(dp[i][j]\):父节点灯\([j==1]\)与否的情况下\(i\)子树及沿向父亲的边的最优解

为什么点灯要从父亲那里设?因为如果设为子树根的情况的话,遍历森林求解ans时会十分繁琐

而父亲节点只要设置一个0的不存在的根,一切都会十分好办

不过这还是取决于编写习惯

还有一个要小心的地方是若父亲情况为0时,子树的根节点也是可以为0的,因为父节点可以是不存在的根

ChromeOS用某IDE无法注释中文,凑合看

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define iin(a) scanf("%d",&a)
#define lin(a) scanf("%lld",&a)
#define din(a) scanf("%lf",&a)
#define s0(a) scanf("%s",a)
#define s1(a) scanf("%s",a+1)
#define print(a) printf("%lld",(ll)a)
#define enter putchar('\n')
#define blank putchar(' ')
#define println(a) printf("%lld\n",(ll)a)
#define IOS ios::sync_with_stdio(0)
using namespace std;
const int maxn = 1e4+11;
const double eps = 1e-10;
typedef long long ll;
const int oo = 0x3f3f3f3f;
ll read(){
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll dp[maxn][2];
int to[maxn<<1],nxt[maxn<<1],head[maxn],tot;
void init(){
memset(head,-1,sizeof head);
tot=0;
}
void add(int u,int v){
to[tot]=v;nxt[tot]=head[u];head[u]=tot++;
swap(u,v);
to[tot]=v;nxt[tot]=head[u];head[u]=tot++;
}
ll M;
// bool isleaf(int u,int fa){
// int cnt=0;
// erep(i,u){
// int v=to[i];
// if(v==fa)continue;
// cnt++;
// if(cnt==1)return 0;
// }
// return 1;
// }
// int deg[maxn];
// ll DP(int u,int fa,int flag){
// if(~dp[u][flag]) return dp[u][flag];
// if(isleaf(u,fa)) return dp[u][flag]=flag*M;
// ll ans=flag*M;
// if(flag==1) erep(i,u){
// int v=to[i];
// if(v==fa)continue;
// ans+=min(DP(v,u,0)+1,DP(v,u,1));
// }else erep(i,u){
// int v=to[i];
// if(v==fa)continue;
// ans+=DP(v,u,1)+1;
// }
// return dp[u][flag]=ans;
// }
bool vis[maxn][2];
ll DP(int u,int fa,int flag){//fujiedianfangdengwei true
if(vis[u][flag])return dp[u][flag];
vis[u][flag]=1; //ru guo u shi gen na ye ke yi bu fang deng jiagen wei 0 gen yewei 0
if(flag==0){
dp[u][0]=M+bool(fa!=0);//virtual root
erep(i,u){
int v=to[i];
if(v==fa)continue;
dp[u][0]+=DP(v,u,1);
}
ll tmp=1ll<<60;
if(fa==0){
tmp=0;
erep(i,u){
int v=to[i];
if(v==fa)continue;
tmp+=DP(v,u,0);
}
}
return dp[u][0]=min(dp[u][0],tmp);//ok
}else{
// dp[u][1]+=min(DP(v,u,1),DP(v,u,0));//cannot dfs
ll tmp1=M;//u fangdeng
erep(i,u){
int v=to[i];
if(v==fa)continue;
tmp1+=DP(v,u,1);
}
ll tmp2=1;//bufangdeng
erep(i,u){
int v=to[i];
if(v==fa)continue;
tmp2+=DP(v,u,0);
}
return dp[u][1]=min(tmp1,tmp2);
}
}
int main(){
int T=read();
while(T--){
init();
memset(dp,-1,sizeof dp);
memset(vis,0,sizeof vis);
int n=read();
int m=read();
rep(i,1,m){
int u=read();u++;
int v=read();v++;
add(u,v);
}
M=2333;
ll ans=0;
rep(i,1,n){
if(!vis[i][0]){
ans+=DP(i,0,0);
}
}
printf("%lld %lld %lld\n",ans/M,m-(ans%M),ans%M);
}
return 0;
}

UVA - 10589 构造最优化函数 DP好题的更多相关文章

  1. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  2. 贪心/构造/DP 杂题选做Ⅲ

    颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...

  3. DP刷题记录(持续更新)

    DP刷题记录 (本文例题目前大多数都选自算法竞赛进阶指南) TYVJ1071 求两个序列的最长公共上升子序列 设\(f_{i,j}\)表示a中的\(1-i\)与b中色\(1-j\)匹配时所能构成的以\ ...

  4. DP百题练(二)

    目录 DP百题练(二) 区间 DP NOI1995 石子合并 IOI1998 Polygon CH5302 金字塔 USACO06FEB Treats for the Cows G/S LG1043 ...

  5. ACM :漫漫上学路 -DP -水题

    CSU 1772 漫漫上学路 Time Limit: 1000MS   Memory Limit: 131072KB   64bit IO Format: %lld & %llu Submit ...

  6. [poj2247] Humble Numbers (DP水题)

    DP 水题 Description A number whose only prime factors are 2,3,5 or 7 is called a humble number. The se ...

  7. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  8. UVA 11137 Ingenuous Cubrency(dp)

    Ingenuous Cubrency 又是dp问题,我又想了2 30分钟,一点思路也没有,最后又是看的题解,哎,为什么我做dp的题这么烂啊! [题目链接]Ingenuous Cubrency [题目类 ...

  9. POJ 1155 TELE 背包型树形DP 经典题

    由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...

随机推荐

  1. 虚拟机Ubuntu16.04安装lrzsz

    [系统环境] 宿主机:Win7 64位 虚拟机软件:Vmware workstation 12 虚拟机:Ubuntu 16.0.4 [目的] 配合Secure CRT使用rz,sz,方便在Ubuntu ...

  2. WCF4.0 –- RESTful WCF Services

    转自:http://blog.csdn.net/fangxinggood/article/details/6235662 WCF 很好的支持了 REST 的开发, 而 RESTful 的服务通常是架构 ...

  3. 数字图像处理实验(10):PROJECT 05-01 [Multiple Uses],Noise Generators 标签: 图像处理MATLAB 2017-05-26 23:36

    实验要求: Objective: To know how to generate noise images with different probability density functions ( ...

  4. Hibernate-Criteria

    Hibernate Criteria简介 一.Criteria接口的用途: 设计上可以灵活的根据criteria的特点进行查询条件的组装. CriteriaSpecification 接口是 Crit ...

  5. C# 用代码返回上一页

    若我们在后台.cs文件中想做到让浏览器返回上一页,我们可以在.cs代码中这样写 Page.ClientScript.RegisterStartupScript(Page.GetType(), &quo ...

  6. 对于 yii2 高级模板 生成文件入口

    安装的 advanced 模板web下是没有index.php 方法: 在advanced 目录下有个init.bat 应用程序  双击即可如下 查看advanced 目录 (刷新)如下 已有:

  7. [GO]map做函数参数

    package main import "fmt" func test(m map[int]string) { delete(m, ) } func main() { m := m ...

  8. Robot Framework - 基础关键字 BuiltIn 库(二)

    本篇教程,我们继续接着上篇内容进行讲解,我们本节教程讲解的是Robot Framework 机器人框架中的变量中使用判断.字符串的拼接.Evaluate的用法.调用Python文件.条件分支语句.以及 ...

  9. css总结11:css的overflow问题

    1 排版时经常遇到块级元素内容overflow,怎么妥当处理是一个关键. overflow的常用属性:  代码: <!DOCTYPE html><html lang="en ...

  10. LightOJ 1258 Making Huge Palindromes (Manacher)

    题意:给定上一个串,让你在后面添加一些字符,使得这个串成为一个回文串. 析:先用manacher算法进行处理如果发现有字符匹配超过最长的了,结束匹配,答案就是该字符前面那个长度加上该串原来的长度. 代 ...