zoukankan      html  css  js  c++  java
  • 【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]$都是普通计算机,那么它的其中一个儿子结点是服务器。
    因此,很容易推导状态转移。
    egin{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] otag \
               &= 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
    ", 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.
    ", clock());
    123     #endif
    124     
    125     return 0;
    126 }
  • 相关阅读:
    coco2d-js demo程序之滚动的小球
    【leetcode】Happy Number(easy)
    【leetcode】Remove Linked List Elements(easy)
    【leetcode】LRU Cache(hard)★
    【QT】计时器制作
    【leetcode】Min Stack(easy)
    【leetcode】Compare Version Numbers(middle)
    【leetcode】Excel Sheet Column Title & Excel Sheet Column Number (easy)
    【leetcode】Binary Search Tree Iterator(middle)
    【leetcode】Number of Islands(middle)
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5336638.html
Copyright © 2011-2022 走看看