[USACO08JAN]Cell Phone Network G 树形dp

Posted 昵称很长很长真是太好了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[USACO08JAN]Cell Phone Network G 树形dp相关的知识,希望对你有一定的参考价值。

题意:
John想让他的所有牛用上手机以便相互交流,他需要建立几座信号塔在N块草地中。已知与信号塔相邻的草地能收到信号。给你N-1个草地(A,B)的相邻关系,问:最少需要建多少个信号塔能实现所有草地都有信号。

思路:
开始思考的是使用dp[x][1/0]来表示结点是否有保安来解决这个问题。
但是细想了一下,父亲结点也会影响改结点的状态转移过程,所以两个结点肯定是不可以的。

d p [ x ] [ 0 / 1 / 2 ] dp[x][0/1/2] dp[x][0/1/2]来表示x结点被自己/儿子/父亲染色的最小染色数。
很容易就可以写出 d p [ x ] [ 0 ] d p [ x ] [ 2 ] dp[x][0] dp[x][2] dp[x][0]dp[x][2]的转移方程
d p [ x ] [ 0 ] + = m i n ( d p [ i ] [ 0 ] , d p [ i ] [ 1 ] , d p [ i ] [ 2 ] ) ; dp[x][0]+=min(dp[i][0],dp[i][1],dp[i][2]); dp[x][0]+=min(dp[i][0],dp[i][1],dp[i][2]); // i i i x x x的孩子结点
d p [ x ] [ 2 ] + = m i n ( d p [ i ] [ 0 ] , d p [ i ] [ 1 ] ) dp[x][2]+=min(dp[i][0],dp[i][1]) dp[x][2]+=min(dp[i][0],dp[i][1])

但是dp[x][1]似乎不是那么好转移,因为只要他有一个孩子染了色,就可以。
所以我们想,只要在保证他最少有一个孩子被染了色的情况下进行
d p [ x ] [ 1 ] + = m i n ( d p [ i ] [ 0 ] , d p [ i ] [ 1 ] ) dp[x][1]+=min(dp[i][0],dp[i][1]) dp[x][1]+=min(dp[i][0],dp[i][1])转移不就可以了。
详情见代码注释。
代码:

//#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
#define endl '\\n'

vector<int> edge[maxn];
int dp[maxn][3];

void dfs(int x,int fa){
    int tot=0;dp[x][0]=1;
    int len=edge[x].size();
    for(auto i:edge[x]){
        if(i==fa) continue;
        dfs(i,x);
        dp[x][0]+=min(dp[i][0],min(dp[i][1],dp[i][2]));
        dp[x][2]+=min(dp[i][0],dp[i][1]);
        if(dp[i][0]>dp[i][1]&&tot<len-2){  
        //至少要保证有一个孩子染色了,并且父亲也连接着这个节点,
        //所以小于len-2
            dp[x][1]+=dp[i][1];tot++;
            //tot记录当前选择了几个没有被染色的孩子结点
            //要保证数量小于len-2
        }
        else dp[x][1]+=dp[i][0];
    }
    if(edge[x].size()==1&&x!=1) dp[x][1]=1e9;
}


signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin>>n;
    for(int i=0;i<n-1;i++){
        int x,y;
        cin>>x>>y;
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    dfs(1,0);
    cout<<min(dp[1][0],dp[1][1])<<endl;
}

以上是关于[USACO08JAN]Cell Phone Network G 树形dp的主要内容,如果未能解决你的问题,请参考以下文章

P1353 [USACO08JAN]跑步Running

[USACO 08JAN]Telephone Lines

[USACO 08JAN]Haybale Guessing

洛谷 P1948 [USACO08JAN]电话线Telephone Lines

P2419 [USACO08JAN]牛大赛Cow Contest

P1353 [USACO08JAN]跑步Running