UVa 1218 - Perfect Service
/*---UVa 1218 - Perfect Service
---首先对状态进行划分:
---dp[u][0]:u是服务器,则u的子节点可以是也可以不是服务器
---dp[u][1]:u不是服务器,但u的父节点是服务器,则u的所有儿子节点都不是服务器
---dp[u][2]:u和u的父亲都不是服务器,则u的儿子恰好有一个是服务器
---状态转移方程:
---dp[u][0]=sum{min(dp[v][0],dp[v][1])}+1
---dp[u][1]=sum(dp[v][2]);
---对于状态dp[u][2],计算略微复杂,这个状态说明u的儿子节点中恰好有一个是服务器,于是需要枚举每一个儿子节点是服务器
---剩下儿子不是服务器的情况,考虑到d(u,1)=sum(dp[v][2]),所以每次枚举时,不必再累加子节点不是服务器的情况,因为这样
---会使得计算一个节点复杂度达到O(k^2),k是u的子节点个数,可以:dp[u][2]=min(dp[u][1]-dp[v][2]+dp[v][0]),枚举v即可
---在实现时,首先递归的构造有根树。然后可以采用记忆化搜索。
---初始化问题,若u是叶子节点,dp[u][0]=1,dp[u][1]=0,dp[u][2]=INF,服务器个数不会超过10000,所以为了保准累加结果不溢出
---可以将INF设置为10000.
*/
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
#define INF 10000+10;
const int maxn = 10000 + 10; int d[maxn][3];
int parent[maxn];
vector<int>vec[maxn]; //构造有根树
void dfs(int u, int fa){
parent[u] = fa;
for (int i = 0; i < vec[u].size(); i++){
int v = vec[u][i];
if (v != fa) dfs(v, u);
}
} int dp(int u, int k){
int&ans = d[u][k];
if (ans >= 0)return ans;
int n = vec[u].size();
if (k == 0)ans = 1;
else if (k == 1)ans = 0;
else ans = INF;
if (n == 1 && parent[u] == vec[u][0]){ //叶节点
return ans;
}
for (int i = 0; i < n; i++){
int v = vec[u][i];
if (v == parent[u])continue; //v是u的父节点,则跳过
if (k == 0)ans += min(dp(v, 0), dp(v, 1));
else if (k == 1) ans += dp(v, 2);
else ans = min(ans, dp(u, 1) - dp(v, 2) + dp(v, 0));
}
return ans;
}
int main(){
int n, i,u,v;
while (scanf("%d", &n)){
for (i = 0; i <= n; i++)vec[i].clear(); for (i = 1; i < n; i++){
scanf("%d%d", &u, &v);
u--, v--;
vec[u].push_back(v);
vec[v].push_back(u);
}
scanf("%d", &v);
dfs(0, -1);
vec[0].push_back(-1);
memset(d, -1, sizeof(d));
int ans = min(dp(0, 0), dp(0, 2));
printf("%d\n", ans);
if (v == -1)break;
}
return 0;
}
UVa 1218 - Perfect Service的更多相关文章
- UVA - 1218 Perfect Service(树形dp)
题目链接:id=36043">UVA - 1218 Perfect Service 题意 有n台电脑.互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连 ...
- UVa 1218 - Perfect Service(树形DP)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 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)(inf相加溢出)
题目链接 题意:给你一个树形图,让你把其中若干个结点染成黑色,其余的染成白色,使得任意一个白色结点都恰好与一个黑色结点相邻. 解法比较容易,和树上的最大独立集类似,取一个结点作为树根,对每个结点分三种 ...
- UVa 1218 Perfect Service 完美的服务
***状态设计值得一看dp[u][0]表示u是服务器(以下v均指任意u的子结点,son指u的所有子结点)ap[u][0]=sum{dp[v][1]}+1//错误,服务器是可以和其他服务器相邻的dp[u ...
- UVA 10622 - Perfect P-th Powers(数论)
UVA 10622 - Perfect P-th Powers 题目链接 题意:求n转化为b^p最大的p值 思路:对n分解质因子,然后取全部质因子个数的gcd就是答案,可是这题有个坑啊.就是输入的能够 ...
- POJ 3398 Perfect Service(树型动态规划,最小支配集)
POJ 3398 Perfect Service(树型动态规划,最小支配集) Description A network is composed of N computers connected by ...
- Perfect Service [POJ 3398]
Perfect Service 描述 网络由N个通过N-1个通信链路连接的计算机组成,使得任何两台计算机可以通过独特的路由进行通信.如果两台计算机之间存在通信链路,则称这两台计算机是相邻的.计算机的邻 ...
- Perfect service(树形dp)
Perfect service(树形dp) 有n台机器形成树状结构,要求在其中一些机器上安装服务器,使得每台不是服务器的计算机恰好和一台服务器计算机相邻.求服务器的最小数量.n<=10000. ...
随机推荐
- 使用ADO.NET 实体数据模型连接MySql
原文:使用ADO.NET 实体数据模型连接MySql 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/a123_z/article/details/8 ...
- SQL视频总结
SQL是英文Structured Query Language的缩写,意思为结构化查询语言. SQL语言的主要功能就是同各种数据库建立联系,进行沟通.SQL被作为关系型数据库管理系统的标准语言. SQ ...
- 软考——(1)J2SE
我们先从Java说起,简单的说,Java是一种面向对象的程序设计语言,可跨平台使用. 与之前学习的程序设计语言相比,最值得一提的就是Java的两种核心机制:Java虚拟机和垃圾回收机制. 1)虚拟机 ...
- 比较运算符compareTo()、equals()、==之间的区别与应用总结
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配 ...
- 《c程序设计语言》读书笔记-5.8-天数和日期转换错误检查
#include "stdio.h" #include "stdlib.h" #include "string.h" static char ...
- Codeforces 938.B Run For Your Prize
B. Run For Your Prize time limit per test 1 second memory limit per test 256 megabytes input standar ...
- H-1-B签证简介
H 1-B签证简介 H 1-B签证是美国雇主为外籍高级技术人员申请的一种工作签证,有效期为3年,可在到期后再延长6年.每年新的配额是6.5万人,另外还有2万个名额是留给在美国获得高级学位(硕士以上学位 ...
- Cisco IPC Emergency Responder Error
Upon startup of the newer Cisco IP Communicator clients (especially on Windows Vista/7), sometimes y ...
- js得到时间戳(10位数)
//从1970年开始的毫秒数然后截取10位变成 从1970年开始的秒数 function timest() { var tmp = Date.parse( new Date() ).toString( ...
- HDU1556---树状数组 | 线段树 |*
输入n,紧接n行,每行a,b n个气球,a,b表示从第a到第b个气球涂一次色,输出每个球最终的涂几次色 暴力超时,优化数据结构 1.树状数组 #include<iostream> #inc ...