UVA - 10589 构造最优化函数 DP好题
题意:给定一个图,节点可以放灯,要求用最少的灯覆盖所有的边(每盏灯能覆盖该节点邻接的边),满足条件的同时求该前提下尽量多的被两盏灯照亮的边数
条件二转化为求尽量少的被一盏灯照亮的边数,两个条件都是求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好题的更多相关文章
- 贪心/构造/DP 杂题选做Ⅱ
由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...
- 贪心/构造/DP 杂题选做Ⅲ
颓!颓!颓!(bushi 前传: 贪心/构造/DP 杂题选做 贪心/构造/DP 杂题选做Ⅱ 51. CF758E Broken Tree 讲个笑话,这道题是 11.3 模拟赛的 T2,模拟赛里那道题的 ...
- DP刷题记录(持续更新)
DP刷题记录 (本文例题目前大多数都选自算法竞赛进阶指南) TYVJ1071 求两个序列的最长公共上升子序列 设\(f_{i,j}\)表示a中的\(1-i\)与b中色\(1-j\)匹配时所能构成的以\ ...
- DP百题练(二)
目录 DP百题练(二) 区间 DP NOI1995 石子合并 IOI1998 Polygon CH5302 金字塔 USACO06FEB Treats for the Cows G/S LG1043 ...
- ACM :漫漫上学路 -DP -水题
CSU 1772 漫漫上学路 Time Limit: 1000MS Memory Limit: 131072KB 64bit IO Format: %lld & %llu Submit ...
- [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 ...
- poj 3254 状压dp入门题
1.poj 3254 Corn Fields 状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...
- UVA 11137 Ingenuous Cubrency(dp)
Ingenuous Cubrency 又是dp问题,我又想了2 30分钟,一点思路也没有,最后又是看的题解,哎,为什么我做dp的题这么烂啊! [题目链接]Ingenuous Cubrency [题目类 ...
- POJ 1155 TELE 背包型树形DP 经典题
由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...
随机推荐
- FlyweightPattern(23种设计模式之一)
设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...
- Apr编程
一.简介 http://www.xuebuyuan.com/2195578.html 二.教程 http://dev.ariel-networks.com/apr/
- 编写高质量代码改善C#程序的157个建议——建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理
建议47:即使提供了显式释放方法,也应该在终结器中提供隐式清理 在标准的Dispose模式中,我们注意到一个以~开头的方法,如下: /// <summary> /// 必须,防止程序员忘记 ...
- Aircrack使用
Aircrack Aircrack-ng 组件功能之一就是采集WEP及WPA-PSK字典并应用无线端口扫描进行破解,具体组件说明如下: aircrack-ng 功能主要是WEP及WPA-PSK密码的恢 ...
- CreateExcel 导出Excel
public class CreateExcel { /// <summary> /// 用Excel组件导出Excel文件 /// </summary> /// <pa ...
- C# -- 泛型(1)
简介: 先看看泛型的概念--“通过参数化类型来实现在同一份代码上操作多种数据类型.利用“参数化类型”将类型抽象化,从而实现灵活的复用”. 很多初学者在刚开始接触泛型的时候会比较难理解 “泛型” 在这里 ...
- 使用Linq读取资源文件
ResXResourceReader resxr = new ResXResourceReader(txt_WebResourceOpenFile.Text); IEnumerable<Dict ...
- C# 多态(2)
接上面讲 我们知道虚方法,和重写方法. 但是有没有发现 override和new的作用是差不多的. 但为什么还要单独写出来两个呢? 首先,咱们要明白一个问题,继承是具有线性传播的. class Fat ...
- 【leetcode 94. 二叉树的中序遍历】解题报告
前往二叉树的:前序,中序,后序 遍历算法 方法一:递归 vector<int> res; vector<int> inorderTraversal(TreeNode* root ...
- C语言字符串拼接
1.使用strcat进行字符串拼接 #include <stdio.h> #include <stdlib.h> #include <string.h> int m ...