BZOJ 1596--电话网络(树形DP)

1596: [Usaco2008 Jan]电话网络

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1139  Solved: 534
[Submit][Status][Discuss]

Description

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计算一下,为了建立能

覆盖到所有草地的通信系统,他最少要建多少座无线电通讯塔。

Input

* 第1行: 1个整数,N

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

Output

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

Sample Input

5
1 3
5 2
4 3
3 5
输入说明:
Farmer John的农场中有5块草地:草地1和草地3相邻,草地5和草地2、草地
4和草地3,草地3和草地5也是如此。

Sample Output

2
输出说明:
FJ可以选择在草地2和草地3,或是草地3和草地5上建通讯塔。

题目链接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=1596

Solution

    简单的树形DP。。。

    dp [ 0 / 1 ] [ i ] 表示第 i 个点没有/有 建立无线电通讯塔时,使以i为根的子树被完全覆盖的最小数量。。

    状态转移方程显然。。。

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define N 10010
#define E 20020
using namespace std;
int n,cnt;
int head[N],dp[N][3];
struct edge{
    int r,next;
}e[E];
void insert(int u,int v){
    e[++cnt].r=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void tree_DP(int x,int F){
    int sum=0;
    dp[x][1]=1;dp[x][0]=N;
    for(int i=head[x];i>0;i=e[i].next)
        if(e[i].r!=F){
            tree_DP(e[i].r,x);
            dp[x][1]+=min(dp[e[i].r][0],min(dp[e[i].r][1],dp[e[i].r][2]));
            dp[x][2]+=dp[e[i].r][0];
            sum+=min(dp[e[i].r][0],dp[e[i].r][1]);
        }
    for(int i=head[x];i>0;i=e[i].next)
        if(e[i].r!=F)
            dp[x][0]=min(dp[x][0],dp[e[i].r][1]+sum-min(dp[e[i].r][0],dp[e[i].r][1]));
}
int main(){
    int x,y,ans;
    cnt=0;
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        scanf("%d%d",&x,&y);
        insert(x,y);
        insert(y,x);
    }
    tree_DP(1,0);
    ans=min(dp[1][0],dp[1][1]);
    printf("%d\n",ans);
    return 0;
}

  

  

This passage is made by Iscream-2001.

时间: 2024-08-28 16:41:17

BZOJ 1596--电话网络(树形DP)的相关文章

bzoj 1131 简单树形dp

思路:随便想想就能想出来啦把...  卡了我一个vector... #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int,int> #define piii pair<int, pair<int,int> > using namespace std; const int

BZOJ 4753 二分+树形DP

思路: 先二分答案 f[x][j]表示在x的子树里选j个点 f[x][j+k]=max(f[x][j+k],f[x][j]+f[v[i]][k]); 初始化 x!=0 -> f[x][1]=p[x]-s[x]*mid x=0 -> f[x][0]=0 类似4033的那样转移 看似O(n^3)实际O(n^2) 加一个二分 复杂度O(能过) //By SiriusRen #include <cstdio> #include <cstring> #include <al

BZOJ 3004 吊灯 树形DP

题目大意:给定一棵树,要求将这棵树分成nk个连通块,每块大小为k,求所有可行的k 首先k一定是n的约数.(废话 然后我们有一个结论:某个k满足条件当且仅当存在nk个节点满足以每个节点为根的子树大小都是k的倍数 证明: 首先不可能存在超过nk个节点满足以每个节点为根的子树大小都是k的倍数,这是废话 首先证明必要性: 假设我们已经有了一组合法的方案,那么对于每一个连通块,我们找到这个连通块中深度最小的节点,以这个节点为根的子树大小一定是k的倍数 由于这样的节点有nk个,因此必要性得证 下面来证明充分

BZOJ 1093 最大半连通子图(强连通分量+树形DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1093 题意: 思路:(1)首先,强连通分量中的一个点若在最大半连通子图中,则必定整个连通分量中的点都在,因为都在还是满足半连通的性质而且使得节点数更多. (2)因此,求出强连通分量缩点,形成一个有向无环图,其实与树是差不多的.在这个图上DP一次即可,也就是找出最长链以及最长链的个数. vector<int> g[N],g1[N]; int n,m,mod; int dfn[N],lo

BZOJ 1924 所驼门王的宝藏(强连通分量+树形DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1924 题意: 思路:首先建立所有可达点之间的有向图.之后求强连通分量SCC,缩点重新构图.然后就是一个树,树形DP一下即可. int n,r,c; map<i64,int> mp; map<int,int> mp1,mp2; struct node { int x,y,op; }; node a[N]; int visit[N]; vector<int> V1

[BZOJ 4033] [HAOI2015] T1 【树形DP】

题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Father[i] 之间的边对答案的贡献(比如这条边对黑点对距离和的贡献就是子树内部的黑点数 * 子树外部的黑点数 * 这条边的权值). 然后DFS来求,枚举 i 的每个儿子 j,现在的 f[i][] 是包含了 [1, j-1] 子树,然后两重循环枚举范围是 [1, j - 1] 的子树总 Size 和

bzoj 3566: [SHOI2014]概率充电器 树形DP

首先普及一个概率公式 P(A+B)=P(A)+P(B)-P(AB) 题意:一些充电元件和导线构成一棵树,充电元件是否能充电有2种情况, 1.它自己有qi%的概率充电 2.与它相邻的元件通过导线给它充电(导线有p%的概率导通) 求最终充了电的元件的期望 题解:首先可以将元件能否充电分成3种情况考虑, 1.它自己给自己充好了电 2.它的儿子方向给它传送了电 3.它的父亲方向给它传送了电. 对于1,题目已经给出可以直接赋值, 对于2,可以通过一次树的深度遍历求得.pson[now]=pson[now]

BZOJ 2878([Noi2012]迷失游乐园-树形DP+环加外向树+期望DP+vector的erase)

2878: [Noi2012]迷失游乐园 Time Limit: 10 Sec  Memory Limit: 512 MBSec  Special Judge Submit: 319  Solved: 223 [Submit][Status] Description 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩.进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐园抽象成有n个景点.m条道路的无向连通图,且该图中至多有一个环(即m只可能等于n或者n-1).小Z现在所在的大门也正好是

BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )

一棵树的话直接树形dp(求出往下走和往上走的期望长度). 假如是环套树, 环上的每棵树自己做一遍树形dp, 然后暴力枚举(环上的点<=20)环上每个点跑经过环上的路径就OK了. --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm&