zoukankan      html  css  js  c++  java
  • UVa 1218

    链接:

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3659

    题意:

    有n(n≤10000)台机器形成树状结构。要求在其中一些机器上安装服务器,
    使得每台不是服务器的计算机恰好和一台服务器计算机相邻。求服务器的最少数量。

    分析:

    按照每个结点的情况进行分类:
    一、d(u,0):u是服务器,则每个子结点可以是服务器也可以不是。
    二、d(u,1):u不是服务器,但u的父亲是服务器,这意味着u的所有子结点都不是服务器。
    三、d(u,2):u和u的父亲都不是服务器。这意味着u恰好有一个儿子是服务器。
    状态转移方程如下(其中v是u的子结点):
    d(u,0) = sum{min(d(v,0), d(v,1))} + 1。
    d(u,1) = sum(d(v,2))。
    d(u,2)需要枚举当服务器的子结点编号v,然后把其他所有子结点v'的d(v',2)加起来,再和d(v,0)相加。
    可以利用已经算出的d(u,1)写出一个新的状态转移方程:d(u,2) = min(d(u,1) – d(v,2) + d(v,0))。
    最终答案为min(d(1,0), d(1,2))。

    代码:

     1 #include <cstdio>
     2 #include <vector>
     3 using namespace std;
     4 
     5 const int UP = 10000 + 5;
     6 int F[UP], d[UP][3]; // F[r]为结点r的父结点
     7 vector<int> seq, edge[UP]; // seq为结点访问顺序序列
     8 
     9 void dfs(int r, int f){
    10     F[r] = f;
    11     seq.push_back(r);
    12     for(int i = 0; i < edge[r].size(); i++){
    13         int b = edge[r][i];
    14         if(b != f) dfs(b, r);
    15     }
    16 }
    17 
    18 int main(){
    19     int n;
    20     while(scanf("%d", &n) == 1){
    21         seq.clear();
    22         for(int i = 1; i <= n; i++) edge[i].clear();
    23         for(int f, b, i = 1; i < n; i++){
    24             scanf("%d%d", &f, &b);
    25             edge[f].push_back(b);
    26             edge[b].push_back(f);
    27         }
    28 
    29         dfs(1, -1); // 以结点1为根建立有根树
    30         for(int p = seq.size() - 1; p >= 0; p--){
    31             int r = seq[p];
    32             d[r][0] = 1;  d[r][1] = 0;
    33             for(int i = 0; i < edge[r].size(); i++){
    34                 int b = edge[r][i];
    35                 if(b == F[r]) continue;
    36                 d[r][0] += min(d[b][0], d[b][1]); // d[r][0]代表r是服务器
    37                 d[r][1] += d[b][2]; // d[r][1]代表r不是服务器,但其父结点是
    38             }
    39             d[r][2] = 12345; //d[r][2]代表r及其父结点都不是服务器
    40             for(int i = 0; i < edge[r].size(); i++){
    41                 int b = edge[r][i];
    42                 if(b == F[r]) continue;
    43                 d[r][2] = min(d[r][2], d[r][1] - d[b][2] + d[b][0]);
    44             }
    45         }
    46         printf("%d
    ", min(d[1][0], d[1][2]));
    47         scanf("%d", &n); // 读取结束标记
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    初识beego
    前端代码
    实现步骤: 跳转-分享-登录-通信录
    实现步骤: 推送&传感器&UIDynamic
    地图显示的步骤
    stackView的隐藏与显示注意事项
    iOS开发的知名大牛博客小汇
    Hidden File For Mac
    file:///Users/xmg/Desktop/xiangmu~Bsbdejie/BaisibudejieTheSecondtime/BaisibudejieTheSecond/BaisibudejieTheSecond/AppDelegate.m: warning: Missing file: /Users/xmg/Desktop/xiangmu~Bsbdejie/BaisibudejieT
    保存相册以及保存图片完成的时候调用
  • 原文地址:https://www.cnblogs.com/hkxy125/p/8628191.html
Copyright © 2011-2022 走看看