• USACO Cell Phone Network


    USACO Cell Phone Network

    洛谷传送门

    JDOJ传送门

    Description

    Farmer John has decided to give each of his cows a cell phone in
    hopes to encourage their social interaction. This, however, requires
    him to set up cell phone towers on his N (1 <= N <= 10,000) pastures
    (conveniently numbered 1..N) so they can all communicate.

    Exactly N-1 pairs of pastures are adjacent, and for any two pastures
    A and B (1 <= A <= N; 1 <= B <= N; A != B) there is a sequence of
    adjacent pastures such that A is the first pasture in the sequence
    and B is the last. Farmer John can only place cell phone towers in
    the pastures, and each tower has enough range to provide service
    to the pasture it is on and all pastures adjacent to the pasture
    with the cell tower.

    Help him determine the minimum number of towers he must install to
    provide cell phone service to each pasture.

    Input

    * Line 1: A single integer: N

    * Lines 2..N: Each line specifies a pair of adjacent pastures with two
    space-separated integers: A and B

    Output

    * Line 1: A single integer indicating the minimum number of towers to
    install

    Sample Input

    5 1 3 5 2 4 3 3 5

    Sample Output

    2

    HINT

    INPUT DETAILS:

    Farmer John has 5 pastures: pastures 1 and 3 are adjacent, as are pastures
    5 and 2, pastures 4 and 3, and pastures 3 and 5. Geometrically, the
    farm looks like this (or some similar configuration)

                   4  2
                   |  |
                1--3--5
    

    OUTPUT DETAILS:

    The towers can be placed at pastures 2 and 3 or pastures 3 and 5.


    题解:

    节点选择类树形DP。

    这类树形DP一般都设好几种互相有着关联的状态,依此相互转移。(啊,我又来瞎YY总结了)

    (%QYB以免被骂)

    所以按套路设状态:

    (dp[i][0/1/2])表示i根子树全被覆盖,且i被自己、父亲、儿子覆盖的最小个数。

    转移也比较好想:

    [dp[x][0]=summin(dp[son][0],dp[son][1],dp[son][2])\dp[x][1]=summin(dp[son][0],dp[son][2])\dp[x][2]=dp[Son][0]+summin(dp[son][0],dp[son][2]) ]

    重点说一下最后这种状态,注意大小写。根据我们的状态,如果这个点被儿子覆盖,那么必然有一个儿子是被选的。即得先选一个儿子覆盖自己,剩下的其他儿子再正常累加。

    那么,如何挑选出这个必须选的Son呢?

    很显然,想要保证(dp[x][2])最优,需要使得这个Son的选择也最优。那么如果当前的选择是最优的,肯定会满足:

    [dp[Son_1][0]+summin(dp[son][0],dp[son][2])<dp[Son_2][0]+summin(dp[son][0],dp[son][2]) ]

    把相同项目消去,即有:

    [dp[son][0]-min(dp[son][0],dp[son][2])>dp[y][0]-min(dp[y][0],dp[y][2]) ]

    然后就有代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn=1e4+10;
    int n;
    int tot,to[maxn<<1],nxt[maxn<<1],head[maxn];
    int dp[maxn][3];
    //dp[i][0/1/2]表示i根子树全被覆盖,且i被自己、父亲、儿子覆盖的最小价值。
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void dfs(int x,int f)
    {
        int son=0;
        dp[x][0]=1;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(y==f)
                continue;
            dfs(y,x);
            dp[x][0]+=min(min(dp[y][0],dp[y][1]),dp[y][2]);
            dp[x][1]+=min(dp[y][0],dp[y][2]);
            if(!son||dp[son][0]-min(dp[son][0],dp[son][2])>dp[y][0]-min(dp[y][0],dp[y][2]))
                son=y;
        }
        if(son)
            dp[x][2]=dp[son][0];
        else
            dp[x][2]=998244353;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(y==f||y==son)
                continue;
            dp[x][2]+=min(dp[y][0],dp[y][2]);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(1,0);
        printf("%d",min(dp[1][0],dp[1][2]));
        return 0;
    }
    
  • 相关阅读:
    python继承__init__函数
    Oracle 用户(user)和模式(schema)的区别【转】
    url增加签名验证防窜改
    Codeforces 每日一练 706C+575H+15C
    Codeforces每日一练 1194D+552C+1117D
    每日一练周赛#2 题解
    AtCoder Beginner Contest 160 题解(F待填坑)
    Codeforces每日一练 1030D+1154E+540D
    Codeforcs 每日一练 678C+527C+1012C
    Codeforces 每日一练922C+725D+1152D
  • 原文地址:https://www.cnblogs.com/fusiwei/p/13814785.html
Copyright © 2020-2023  润新知