• [Usaco2008 Jan]电话网络


     [Usaco2008 Jan]电话网络

    描述

    Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流。不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号。所有的N块草地按1..N 顺次编号。 所有草地中只有N-1对是相邻的,不过对任意两块草地A和B(1 <= A <= N; 1 <= B <= N; A != B),都可以找到一个以A开头以B结尾的草地序列,并且序列中相邻的编号所代表的草地相邻。无线电通讯塔只能建在草地上,一座塔的服务范围为它所在的那块草地,以及与那块草地相邻的所有草地。 请你帮FJ计算一下,为了建立能覆盖到所有草地的通信系统,他最少要建多少座无线电通讯塔。

    输入

    第1行: 1个整数,N

    * 第2..N行: 每行为2个用空格隔开的整数A、B,为两块相邻草地的编号

    输出

    * 第1行: 输出1个整数,即FJ最少建立无线电通讯塔的数目

    样例

    输入

    5
    1 3
    5 2
    4 3
    3 5
    输入说明:
    Farmer John的农场中有5块草地:草地1和草地3相邻,草地5和草地2、草地
    4和草地3,草地3和草地5也是如此。更形象一些,草地间的位置关系大体如下:
    (或是其他类似的形状)
    

    输出

    2
    输出说明:
    FJ可以选择在草地2和草地3,或是草地3和草地5上建通讯塔
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,head[1000001],tot,f[10001][3];
     4 //f[i][0] i被自己覆盖
     5 //f[i][1] i被儿子覆盖 
     6 //f[i][2] i被父亲覆盖
     7 //f[i][0]+=min(f[son][1],f[son][2],f[son][0]) 
     8 //f[i][1]=f[x][0]+sigma(min (f[son][0],f[son][1]) ) 
     9 //f[i][2]+=min(f[son][0],f[son][1])
    10 struct data {
    11     int to,nxt;
    12 } e[1000001];
    13 void add(int x,int y) {
    14     e[++tot].to=y;
    15     e[tot].nxt=head[x];
    16     head[x]=tot;
    17 }
    18 void dp(int x,int fa) {
    19     int special_son=0;
    20     f[x][0]=1;
    21     for(int i=head[x]; i; i=e[i].nxt) {
    22         int v=e[i].to;
    23         if(v==fa)
    24             continue;
    25         dp(v,x);
    26         f[x][2]+=min(f[v][0],f[v][1]);
    27         f[x][0]+=min(min(f[v][0],f[v][1]),f[v][2]);
    28         if(f[special_son][0]-min(f[special_son][0],f[special_son][1])>f[v][0]-min(f[v][1],f[v][0]))
    29             special_son=v;    
    30     }
    31     f[x][1]=f[special_son][0];
    32     for(int i=head[x];i;i=e[i].nxt){
    33         int v=e[i].to;
    34         if(v==fa||v==special_son)
    35             continue;
    36         f[x][1]+=min(f[v][1],f[v][0]);
    37     }
    38 }
    39 int main() {
    40     scanf("%d",&n);
    41     for(int i=1,x,y; i<n; i++) {
    42         scanf("%d%d",&x,&y);
    43         add(x,y);
    44         add(y,x);
    45     }
    46     f[0][0]=0x3f;
    47     dp(1,-1);
    48     printf("%d
    ",f[1][1]<f[1][0]?f[1][1]:f[1][0]);
    49     return 0;
    50 }
  • 相关阅读:
    利用相关的Aware接口
    java 值传递和引用传递。
    权限控制框架Spring Security 和Shiro 的总结
    优秀代码养成
    Servlet 基础知识
    leetcode 501. Find Mode in Binary Search Tree
    leetcode 530. Minimum Absolute Difference in BST
    leetcode 543. Diameter of Binary Tree
    leetcode 551. Student Attendance Record I
    leetcode 563. Binary Tree Tilt
  • 原文地址:https://www.cnblogs.com/sbwll/p/13399442.html
Copyright © 2020-2023  润新知