UVA - 1218 Perfect Service(树形dp)
题目链接: id=36043">UVA - 1218 Perfect Service
题意
有n台电脑。互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连接且仅仅能连接一台server(不包含作为server的电脑)。求最少须要多少台电脑作为server。
思路
典型的树形dp问题,那么我们来建立模型。
d(u,0):u是server,孩子是不是server均可
d(u,1):u不是server,u的父亲是server,u的孩子不能是server
d(u,2):u不是server且u的父亲不是server,u的孩子必须有且仅有一个是server。那么显然的
d(u,0) = 1 + Sum( Min(d(v,1), d(v,0)) ) |v是u的孩子
d(u,1) = Sum(d(v,2))
d(u,2)稍复杂些。由于仅仅能有一个孩子是server,所以须要遍历每一个孩子为server的情况,每一轮遍历都要同一时候计算其它全部孩子,须要O(N^2)的时间。
显然这样会有非常多反复计算的情况,当然能够记忆化来加高速度,可是另一个更快的小技巧。由于d(u,1)和d(u,2)的唯一差别就是d(u,2)的孩子有一个server
那么我们能够得出
d(u,2) = Min(d(u,1)-d(v,2)+d(v,0)) |v是u的孩子
仍是遍历设每一个孩子为server。每一轮的操作为O(1),整体为O(N)
代码
ps:由于d(u,2)初始要设为无穷大,就设了0x3f3f3f3f,结果改成N就好了,找了好久才找出问题出在这,由于这个wrong了好多遍,但还是不知道为什么会wrong,知道原因的道友请不吝指点。
第一遍a的代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
const int N = 10009;
vector<int> g[N];
int dp[N][3];
void dfs(int u, int fa)
{
for(int i=0; i<g[u].size(); i++)
{
if(g[u][i] != fa)
dfs(g[u][i], u);
}
dp[u][0] = 1;
dp[u][1] = 0;
dp[u][2] = N;
for(int i=0; i<g[u].size(); i++)
{
if(g[u][i] != fa)
{
dp[u][0] += min(dp[g[u][i]][0], dp[g[u][i]][1]);
dp[u][1] += dp[g[u][i]][2];
}
}
bool f = true;
for(int i=0; i<g[u].size(); i++)
{
if(g[u][i] != fa)
{
f = false;
dp[u][2] = min(dp[u][2], dp[u][1]+dp[g[u][i]][0]-dp[g[u][i]][2]);
}
}
}
int main()
{
int n;
while(cin>>n)
{
memset(dp, -1, sizeof(dp));
int a, b;
for(int i=1; i<n; i++)
{
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1, -1);
cout<<min(dp[1][0], dp[1][2])<<endl;
cin>>a;
if(a == -1)
break;
for(int i=1; i<=n; i++)
g[i].clear();
}
return 0;
}
观摩大神代码后进行改动的精简版
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
const int N = 10009;
vector<int> g[N];
int dp[N][3];
void dfs(int u, int fa)
{
dp[u][0] = 1;
dp[u][1] = 0;
dp[u][2] = N;
for(int i=0; i<g[u].size(); i++)
{
if(g[u][i] != fa)
{
dfs(g[u][i], u);
dp[u][0] += min(dp[g[u][i]][0], dp[g[u][i]][1]);
dp[u][1] += dp[g[u][i]][2];
}
}
for(int i=0; i<g[u].size(); i++)
{
if(g[u][i] != fa)
dp[u][2] = min(dp[u][2], dp[u][1]+dp[g[u][i]][0]-dp[g[u][i]][2]);
}
}
int main()
{
int n;
while(cin>>n)
{
int a, b;
for(int i=1; i<n; i++)
{
cin>>a>>b;
g[a].push_back(b);
g[b].push_back(a);
}
dfs(1, -1);
cout<<min(dp[1][0], dp[1][2])<<endl;
cin>>a;
if(a == -1)
break;
for(int i=1; i<=n; i++)
g[i].clear();
}
return 0;
}
UVA - 1218 Perfect Service(树形dp)的更多相关文章
- UVA - 1218 Perfect Service (树形dp)(inf相加溢出)
题目链接 题意:给你一个树形图,让你把其中若干个结点染成黑色,其余的染成白色,使得任意一个白色结点都恰好与一个黑色结点相邻. 解法比较容易,和树上的最大独立集类似,取一个结点作为树根,对每个结点分三种 ...
- UVa 1218 - Perfect Service
/*---UVa 1218 - Perfect Service ---首先对状态进行划分: ---dp[u][0]:u是服务器,则u的子节点可以是也可以不是服务器 ---dp[u][1]:u不是服务器 ...
- UVA - 1218 Perfect Service (树形DP)
思路:dp[i][0]表示i是服务器:dp[i][1]表示i不是服务器,但它的父节点是服务器:dp[i][2]表示i和他的父亲都不是服务器. 转移方程: d[u][0] += min(d[ ...
- UVa 1218 - Perfect Service(树形DP)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVa 1218 Perfect Service 完美的服务
***状态设计值得一看dp[u][0]表示u是服务器(以下v均指任意u的子结点,son指u的所有子结点)ap[u][0]=sum{dp[v][1]}+1//错误,服务器是可以和其他服务器相邻的dp[u ...
- POJ3398Perfect Service[树形DP 树的最大独立集变形]
Perfect Service Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 1518 Accepted: 733 De ...
- UVa 10859 - Placing Lampposts 树形DP 难度: 2
题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&a ...
- UVa 1292 - Strategic game (树形dp)
本文出自 http://blog.csdn.net/shuangde800 题目链接: 点击打开链接 题目大意 给定一棵树,选择尽量少的节点,使得每个没有选中的结点至少和一个已选结点相邻. 思路 ...
- Uva LA 3902 - Network 树形DP 难度: 0
题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...
随机推荐
- PIR人体检查
1.无变化时电压为0.8V左右 2.当检查到人体活动,电压保持为-1.3V,直到运动停止. 下面是示波器的截图
- Qt 事件处理机制 (上篇)
本篇来介绍Qt 事件处理机制 .深入了解事件处理系统对于每个学习Qt人来说非常重要,可以说,Qt是以事件驱动的UI工具集. 大家熟知Signals/Slots在多线程的实现也依赖于Qt的事件处理机制. ...
- [置顶] JDK工具(一)–Java编译器javac
1.概述 javac.exe: Java编译器,将Java源代码转换成字节码. 2.用法 javac <选项> <源文件> (使用过程中发现,javac <源 ...
- RV BaseRecyclerViewAdapterHelper 总结 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- WebUploader文件图片上传插件的使用
最近在项目中用到了百度的文件图片上传插件WebUploader.分享给大家 需要在http://fex.baidu.com/webuploader/download.html点击打开链接下载WebUp ...
- #pragma详细解释(一)
#pragma详细解释 #pragma详细解释(一) 2010-04-18 14:21:00| 分类: 默认分类 | 标签: |字号大中小订阅 在#Pragma是预处理指令它的作用是设定编 ...
- PHP的错误处理方式(开发和上线)
对于PHP开发人员来说,一旦某个产品投入使用.应该马上将 display_errors选项关闭.以免由于这些错误所透露的路径.数据库连接.数据表等信息而遭到黑客攻击. 可是.不论什么一个产品在投入使用 ...
- 稍复杂的ionic例子:显示一个列表,并且允许点击进入列表项
这个例子,按照MVC的方式进行了分层,下面是代码: demo3.htm <!DOCTYPE html> <html ng-app="app"> <he ...
- Oracle 之 分析函数
一.分析函数 1.分析函数 分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值. 2.分析函数 ...
- UML学习(一)-工具介绍
这里用于学习UML的工具是StarUML,没有什么原因为什么要用它,或许仅仅是有人说好用和比较小. 首先介绍下这个工具,来张图. 1.菜单栏(最上面) 2.快捷工具栏(菜单栏下面) 3.工具项(Too ...