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 ...
随机推荐
- 固定的价格就意味着背叛——《practices of an agile developper》
“对这个项目,我们必须要有固定的报价.虽然我们还不清楚项目的具体情况,但仍要有一个报价.到星期一,我需要整个团队的评估,并且我们必须要在年末交付整个项目.” Venkat & Andy 提出了 ...
- Oracle sql"NOT IN"语句优化,查询A表有、B表没有的数据
记录量大的情况下,采用NOT IN查询,那肯定会慢的无法接受.比如: SELECT A.* FROM TABLE_A WHERE A.USER_ID NOT IN (SELECT B.USER_ID ...
- 纠正jQuery获取radio选中值的写法
先看一段代码 <input type="radio" name="aaa" value="1" checked="true& ...
- 高性能server框架--I/O模型
socket在创建的时候默认是堵塞的.我们能够通过socket系统调用的第二个參数传递SOCK_NONBLOCK标志,或者通过fcntl系统调用的F_SETFL命令,将其设置为非堵塞的. 堵塞和非堵塞 ...
- 【python】列出http://www.cnblogs.com/xiandedanteng中所有博文的标题
代码: # 列出http://www.cnblogs.com/xiandedanteng中所有博文的标题 from bs4 import BeautifulSoup import requests u ...
- (剑指Offer)面试题43:n个骰子的点数
题目: 把n个骰子仍在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 思路: s可能出现的值的范围为:n--6*n 1.全排列 回溯法枚举n个骰子(6面)的全排列,然 ...
- 【Caffe代码解析】Layer网络层
Layer 功能: 是全部的网络层的基类,当中.定义了一些通用的接口,比方前馈.反馈.reshape,setup等. #ifndef CAFFE_LAYER_H_ #define CAFFE_LAYE ...
- Struts2之文件上传(单文件/多文件)
<一>简述: Struts2的文件上传其实也是通过拦截器来实现的,只是该拦截器定义为默认拦截器了,所以不用自己去手工配置,<interceptor name="fileUp ...
- Java生成各种条形码
import java.awt.image.BufferedImage; import java.io.FileOutputStream; import org.jbarcode.JBarcode; ...
- Python 整数和浮点数运算
和数学运算不同的地方是,Python的整数运算结果仍然是整数,浮点数运算结果仍然是浮点数:1 + 2 # ==> 整数 31.0 + 2.0 # ==> 浮点数 3.0 整数和浮点数混合运 ...