zoukankan      html  css  js  c++  java
  • UVa 1218 完美的服务

    https://vjudge.net/problem/UVA-1218

    题意:

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

    思路:

    和紫书上前面的UVa1220挺像的,不过这题是一棵无根树,就把0当做根就行了,方法还是一样的dfs。

    d[u][0]:u是服务器,则每个子结点可以是服务器也可以不是。

    d[u][1]:u不是服务器,但u的父亲是服务器,这意味着u的所有子结点都不是服务器。

    d[u][2]:u和u的父亲都不是服务器。这意味着u恰好有一个儿子是服务器。

    状态转移方程分析:

    d[u][0]:由于它已经是服务器了,所以子结点可以是也可以不是,选择小的,d[u][1]=sum{min(d[v][0],d[v][1])}+1。1代表它自身这个服务器。

    d[u][1]:u的父亲是服务器,那么与它相连的就不可能是服务器了,此时很简单,d[u][1]=sum(d[v][2])

    d[u][2]:子结点有且仅有一个服务器,也就是说d[u][2]=min(d[u][2],d[v1][2]+d[v2][2].....+d[v][0])。由于前面已经算出了所有子结点的d[v][2]和,所以这里可以简化为d[u][2]=min(d[u][2],d[u][1]-d[v][2]+d[v][0])

     1 #include<iostream> 
     2 #include<string>
     3 #include<cstring>
     4 #include<vector>
     5 #include<algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 10000 + 5;
     9 
    10 int n, cnt;
    11 
    12 vector<int> sons[maxn];
    13 
    14 int d[maxn][3];
    15 
    16 void dfs(int u,int fa)
    17 {
    18     d[u][0] = 1;   //加上自身为服务器
    19     d[u][1] = 0;
    20     d[u][2] = maxn;
    21     int k = sons[u].size();
    22     if (k == 1 && fa != 0)  return; //树的叶子节点
    23     for (int i = 0; i < k; i++)
    24     {
    25         int son = sons[u][i];
    26         if (fa == son) continue;
    27         dfs(son,u);
    28         d[u][0] += min(d[son][0], d[son][1]);
    29         d[u][1] += d[son][2];
    30     }
    31     for (int i = 0; i < k; i++)
    32     {
    33         int son = sons[u][i];
    34         if (son == fa)  continue;
    35         d[u][2] = min(d[u][2], d[u][1] - d[son][2] + d[son][0]);
    36     }
    37 }
    38 
    39 int main()
    40 {
    41     //freopen("D:\txt.txt", "r", stdin);
    42     int a, b;
    43     while (cin >> n)
    44     {
    45         for (int i = 1; i <= n; i++)
    46             sons[i].clear();
    47         for (int i = 1; i < n; i++)
    48         {
    49             cin >> a >> b;
    50             sons[a].push_back(b);
    51             sons[b].push_back(a);
    52         }
    53         dfs(1,0);
    54         cout << min(d[1][0], d[1][2]) << endl;    
    55         cin >> a;
    56         if (a == -1)  break;
    57     }
    58     return 0;
    59 }
  • 相关阅读:
    《计算机网络 自顶向下方法》 第3章 运输层 Part1
    Java 字符串截取问题
    Java 字符排序问题
    Linux 下实时查看日志
    Java项目 打war包方法
    Linux 下 安装jdk 1.7
    Linux 下安装jetty服务器
    Linux 系统下安装 rz/sz 命令及使用说明
    Xshell
    Linux 常用命令大全
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6375959.html
Copyright © 2011-2022 走看看