【POJ】3398 Perfect Service

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. 代码

  1 /* 3398 */
  2 #include <iostream>
  3 #include <sstream>
  4 #include <string>
  5 #include <map>
  6 #include <queue>
  7 #include <set>
  8 #include <stack>
  9 #include <vector>
 10 #include <deque>
 11 #include <bitset>
 12 #include <algorithm>
 13 #include <cstdio>
 14 #include <cmath>
 15 #include <ctime>
 16 #include <cstring>
 17 #include <climits>
 18 #include <cctype>
 19 #include <cassert>
 20 #include <functional>
 21 #include <iterator>
 22 #include <iomanip>
 23 using namespace std;
 24 //#pragma comment(linker,"/STACK:102400000,1024000")
 25
 26 #define sti                set<int>
 27 #define stpii            set<pair<int, int> >
 28 #define mpii            map<int,int>
 29 #define vi                vector<int>
 30 #define pii                pair<int,int>
 31 #define vpii            vector<pair<int,int> >
 32 #define rep(i, a, n)     for (int i=a;i<n;++i)
 33 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
 34 #define clr                clear
 35 #define pb                 push_back
 36 #define mp                 make_pair
 37 #define fir                first
 38 #define sec                second
 39 #define all(x)             (x).begin(),(x).end()
 40 #define SZ(x)             ((int)(x).size())
 41 #define lson            l, mid, rt<<1
 42 #define rson            mid+1, r, rt<<1|1
 43 #define INF                0x3f3f3f3f
 44 #define mset(a, val)    memset(a, (val), sizeof(a))
 45
 46 typedef struct {
 47     int v, nxt;
 48 } edge_t;
 49
 50
 51 const int maxv = 10005;
 52 const int inf = 1e5;
 53 const int maxe = maxv * 2;
 54 int head[maxv], l;
 55 edge_t E[maxe];
 56 int dp[maxv][3];
 57 int n;
 58
 59 void init() {
 60     memset(head, -1, sizeof(head));
 61     l = 0;
 62 }
 63
 64 inline void addEdge(int u, int v) {
 65     E[l].v = v;
 66     E[l].nxt = head[u];
 67     head[u] = l++;
 68
 69     E[l].v = u;
 70     E[l].nxt = head[v];
 71     head[v] = l++;
 72 }
 73
 74 void dfs(int u, int fa) {
 75     int k;
 76
 77     dp[u][0] = 1;
 78     dp[u][1] = 0;
 79     dp[u][2] = inf;
 80     for (k=head[u]; k!=-1; k=E[k].nxt) {
 81         int& v = E[k].v;
 82         if (v == fa)
 83             continue;
 84         dfs(v, u);
 85         dp[u][0] += min(dp[v][0], dp[v][1]);
 86         dp[u][1] += dp[v][2];
 87         dp[u][2] = min(dp[u][2], dp[v][0]-dp[v][2]);
 88     }
 89
 90
 91     dp[u][2] += dp[u][1];
 92 }
 93
 94 void solve() {
 95     dfs(1, 0);
 96     int ans = min(dp[1][0], dp[1][2]);
 97     printf("%d\n", ans);
 98 }
 99
100 int main() {
101     ios::sync_with_stdio(false);
102     #ifndef ONLINE_JUDGE
103         freopen("data.in", "r", stdin);
104         freopen("data.out", "w", stdout);
105     #endif
106
107     int u, v;
108
109     while (scanf("%d",&n)!=EOF && n) {
110         init();
111         rep(i, 1, n) {
112             scanf("%d%d",&u,&v);
113             addEdge(u, v);
114         }
115         solve();
116         scanf("%d", &n);
117         if (n == -1)
118             break;
119     }
120
121     #ifndef ONLINE_JUDGE
122         printf("time = %ldms.\n", clock());
123     #endif
124
125     return 0;
126 }
时间: 2024-10-11 11:45:47

【POJ】3398 Perfect Service的相关文章

【题解】UVA1218 Perfect Service

UVA1218:https://www.luogu.org/problemnew/show/UVA1218 刷紫书DP题ing 思路 参考lrj紫书 不喜勿喷 d(u,0):u是服务器,孩子是不是服务器均可 d(u,1):u不是服务器,u的父亲是服务器,u的孩子不能是服务器 d(u,2):u不是服务器且u的父亲不是服务器,u的孩子必须有且仅有一个是服务器. 前两个状态方程好写 那么d(u,2)呢? d(u,2)就会等于 他儿子全都不是 减去某个不是 再加上某个是 这是这道树形DP的难点 因此 状

【POJ】2278 DNA Sequence

各种wa后,各种TLE.注意若AC非法,则ACT等一定非法.而且尽量少MOD. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 105 8 #define NXTN 4 9 10 char str[15]; 11 12 typedef struct Matrix {

【Android】Android中Service类onStartCommand的返回值有关问题(转)

@Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("---------->>onStartCommand2"); return super.onStartCommand(intent, flags, startId); } Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象

【POJ】1739 Tony&#39;s Tour

http://poj.org/problem?id=1739 题意:n×m的棋盘,'#'是障碍,'.'是空白,求左下角走到右下角且走过所有空白格子的方案数.(n,m<=8) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; #define BIT(a,b) ((a)<<((b)<<1)) #

【POJ】2449 Remmarguts&#39; Date(k短路)

http://poj.org/problem?id=2449 不会.. 百度学习.. 恩. k短路不难理解的. 结合了a_star的思想.每动一次进行一次估价,然后找最小的(此时的最短路)然后累计到k 首先我们建反向边,跑一次从汇到源的最短路,将跑出来的最短路作为估价函数h 根据f=g+h 我们将源s先走,此时实际价值g为0,估价为最短路(他们的和就是s-t的最短路) 将所有s所连的边都做相同的处理,加入到堆中(假设此时到达的点为x,那么x的g等于s到这个点的边权,因为根据最优,g+h此时是从x

【POJ】2318 TOYS ——计算几何+二分

TOYS Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10281   Accepted: 4924 Description Calculate the number of toys that land in each bin of a partitioned toy box. Mom and dad have a problem - their child John never puts his toys away w

【POJ】3009 Curling 2.0 ——DFS

Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11432   Accepted: 4831 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. But the rules are somewhat different from ours. The game is

【POJ】1056 IMMEDIATE DECODABILITY

字典树水题. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 typedef struct Trie { 6 bool v; 7 Trie *next[2]; 8 } Trie; 9 10 Trie *root; 11 12 bool create(char str[]) { 13 int i = 0, id; 14 bool ret = false; 15 Trie *p = root

【POJ】2418 Hardwood Species

简单字典树. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXN 128 6 7 typedef struct Trie { 8 int count; 9 Trie *next[MAXN]; 10 Trie() { 11 count = 0; 12 for (int i=0; i<MAXN; ++i) 13 next[i] = NULL; 14 } 15 }