1. 题目描述
某树形网络由$n, n \in [1, 10^4]$台计算机组成。现从中选择一些计算机作为服务器,使得每当普通计算机恰好与一台服务器连接(并且不超过一台)。求需要指定服务器的最少数量

2. 基本思路
这显然是一个求最优解的问题,并且该网络拓扑结构为树形。因此,考虑树形DP。关键是考虑有哪些状态?不妨令
(1) $dp[u][0]$表示$u$作为服务器,那么它的儿子结点可以是服务器或者普通机;
(2) $dp[u][1]$表示$u$是普通计算机,但是$fa[u]$作为服务器,那么它的儿子结点一定是普通机;
(3) $dp[u][2]$表示$u$和$fa[u]$都是普通计算机,那么它的其中一个儿子结点是服务器。
因此,很容易推导状态转移。
\begin{align}
  dp[u][0] &= 1 + \sum \min (dp[v][0], dp[v][1])  \\
  dp[u][1] &= \sum dp[v][2] \\
  dp[u][2] &= \min (dp[v][0] - dp[v][2]) + \sum dp[v][2] \notag \\
           &= \min (dp[v][0] - dp[v][2]) + dp[u][1]
\end{align}
这里注意所求解是$\min (dp[rt][0], dp[rt][2])$,因为根节点没有父亲节点。这是树形DP中很经典的模型。

3. 代码

 /* 3398 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
#define INF 0x3f3f3f3f
#define mset(a, val) memset(a, (val), sizeof(a)) typedef struct {
int v, nxt;
} edge_t; const int maxv = ;
const int inf = 1e5;
const int maxe = maxv * ;
int head[maxv], l;
edge_t E[maxe];
int dp[maxv][];
int n; void init() {
memset(head, -, sizeof(head));
l = ;
} inline void addEdge(int u, int v) {
E[l].v = v;
E[l].nxt = head[u];
head[u] = l++; E[l].v = u;
E[l].nxt = head[v];
head[v] = l++;
} void dfs(int u, int fa) {
int k; dp[u][] = ;
dp[u][] = ;
dp[u][] = inf;
for (k=head[u]; k!=-; k=E[k].nxt) {
int& v = E[k].v;
if (v == fa)
continue;
dfs(v, u);
dp[u][] += min(dp[v][], dp[v][]);
dp[u][] += dp[v][];
dp[u][] = min(dp[u][], dp[v][]-dp[v][]);
} dp[u][] += dp[u][];
} void solve() {
dfs(, );
int ans = min(dp[][], dp[][]);
printf("%d\n", ans);
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int u, v; while (scanf("%d",&n)!=EOF && n) {
init();
rep(i, , n) {
scanf("%d%d",&u,&v);
addEdge(u, v);
}
solve();
scanf("%d", &n);
if (n == -)
break;
} #ifndef ONLINE_JUDGE
printf("time = %ldms.\n", clock());
#endif return ;
}

【POJ】3398 Perfect Service的更多相关文章

  1. 【题解】UVA1218 Perfect Service

    UVA1218:https://www.luogu.org/problemnew/show/UVA1218 刷紫书DP题ing 思路 参考lrj紫书 不喜勿喷 d(u,0):u是服务器,孩子是不是服务 ...

  2. POJ 3398 Perfect Service(树型动态规划,最小支配集)

    POJ 3398 Perfect Service(树型动态规划,最小支配集) Description A network is composed of N computers connected by ...

  3. 【POJ】1704 Georgia and Bob(Staircase Nim)

    Description Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, ...

  4. 【POJ】1067 取石子游戏(博弈论)

    Description 有两堆石子,数量任意,可以不同.游戏开始由两个人轮流取石子.游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子:二是可以在两堆中同时取走相同数量的石子.最后 ...

  5. 【BZOJ1820】[JSOI2010]Express Service 快递服务 暴力DP

    [BZOJ1820][JSOI2010]Express Service 快递服务 Description 「飞奔」快递公司成立之后,已经分别与市内许多中小企业公司签订邮件收送服务契约.由于有些公司是在 ...

  6. 【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉

    DP/单调队列优化 首先不考虑奶牛的喜欢区间,dp方程当然是比较显然的:$ f[i]=min(f[k])+1,i-2*b \leq k \leq i-2*a $  当然这里的$i$和$k$都是偶数啦~ ...

  7. 【POJ】【2104】区间第K大

    可持久化线段树 可持久化线段树是一种神奇的数据结构,它跟我们原来常用的线段树不同,它每次更新是不更改原来数据的,而是新开节点,维护它的历史版本,实现“可持久化”.(当然视情况也会有需要修改的时候) 可 ...

  8. 【POJ】1222 EXTENDED LIGHTS OUT

    [算法]高斯消元 [题解] 高斯消元经典题型:异或方程组 poj 1222 高斯消元详解 异或相当于相加后mod2 异或方程组就是把加减消元全部改为异或. 异或性质:00 11为假,01 10为真.与 ...

  9. 【POJ】2892 Tunnel Warfare

    [算法]平衡树(treap) [题解]treap知识见数据结构 在POJ把语言从G++换成C++就过了……??? #include<cstdio> #include<algorith ...

随机推荐

  1. BZOJ 1012: [JSOI2008]最大数maxnumber 线段树

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1012 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能: ...

  2. 【BZOJ】【1269】【AHOI2006】文本编辑器editor

    Splay Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build.splay和Findkth这三个操作,我们可以实现 ...

  3. [工作记录] Android OpenGL ES: non-square texture - continue

    previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...

  4. 将apk安装包安装在Android真机或者模拟器

    例子如下: 一.准备 打开MAC PC上的Android模拟器方法:打开eclipse-—>window->Android Virtual Device Manager 如果是安装在真机上 ...

  5. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  6. C++时间标准库时间time和系统时间的使用

    #include <iostream> #include <time.h> #include <stdio.h> #include <windows.h> ...

  7. mysql 数据库优化

    提到优化,先要确定出现的问题,是存储引擎选择问题,还是sql语句使用问题(如:索引)亦或者是单一存储服务器对于千万级别的数据力不从心. 解决方法:1.根据不同业务选用不同存储引擎,虽然一般情况下都优先 ...

  8. HDU 2674 N!Again(数学思维水题)

    题目 //行开始看被吓一跳,那么大,没有头绪, //看了解题报告,发现这是一道大大大的水题,,,,,//2009 = 7 * 7 * 41//对2009分解,看它有哪些质因子,它最大的质因子是41,那 ...

  9. iOS视频压缩

    // // ViewController.m // iOS视频测试 // // Created by apple on 15/8/19. // Copyright (c) 2015年 tqh. All ...

  10. Visual Studio 项目中添加include, lib, dll库文件(*.h,*.lib,*.dll)

    应用程序使用外部库时需要进行加载,两种库的加载本质上都是一样:提供功能和功能的定义.vs2005 c++ 项目设置外部库方法如下: 1. 添加编译所需要(依赖)的 lib 文件     在“项目-&g ...