1010 电话网络 最小支配集

 链接:https://ac.nowcoder.com/acm/contest/25022/1010
来源:牛客网

题目描述

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最少建立无线电通讯塔的数目
示例1

输入

复制
5
1 3
5 2
4 3
3 5

输出

复制
2

分析

就是问最小的让所有点都能被覆盖的数量。

跟1003完全一样的最小支配集问题。

//-------------------------代码----------------------------

//#define int ll
const int N = 2e6+10;
int n,m;
int ne[N],e[N],w[N],h[N],idx;
int dp[N][3];
void add(int a,int b) {
    e[idx] = b,ne[idx] = h[a],h[a] = idx ++ ;
}

void dfs(int u,int fa) {
    dp[u][0] = 1;
    dp[u][1] = 0;
    dp[u][2] = 0;
    int inc = inf;
    for(int i = h[u];~i;i=ne[i]) {
        int j = e[i];
        if(j == fa) continue;
        dfs(j,u);
        dp[u][0] += min({dp[j][1],dp[j][2],dp[j][0]});
        dp[u][2] += min(dp[j][1],dp[j][0]);
        dp[u][1] += min(dp[j][0],dp[j][1]);
        inc = min(inc,dp[j][0] - dp[j][1]);
    }
    if(inc < 0) inc = 0;
    dp[u][1] += inc;
}

void solve()
{
    cin>>n;
    ms(h,-1);
    fo(i,1,n-1) {
        int a,b;cin>>a>>b;
        add(a,b);
        add(b,a);
    }
    dfs(1,-1);
    cout<<min(dp[1][1],dp[1][0])<<endl;
}

signed main(){
    clapping();TLE;

//    int t;cin>>t;while(t -- )
    solve();
//    {solve(); }
    return 0;
}

/*样例区


*/

//------------------------------------------------------------

 

posted @ 2022-08-02 14:34  er007  阅读(28)  评论(0编辑  收藏  举报