【树形DP】BZOJ1596-[Usaco2008 Jan]电话网络

【题目大意】

在一棵有n个节点的树上建信号塔,每个节点的信号塔可以覆盖当前节点极其相连的节点。问要覆盖所有节点,至少需要多少座信号塔?

【思路】

经典的树形DP,直接复制一下。

f[i][0]:以i为根的子树中所有点均被覆盖且草地i上无信号塔所需的最小塔数(i被其儿子覆盖)

f[i][1]:以i为根的子树中所有点均被覆盖且草地i上有信号塔所需的最小塔数

f[i][2]:以i为根的子树中除i点以外其余点均被覆盖所需的最小塔数

f[i][0]=至少有一个儿子有塔的最小情况。所以这样处理:每次取f[j][0]和f[j][1]中较小的,如果有一个满足f[j][1]<f[j][0],OK。如果对于所有的儿子,f[j][0]较小,存下min(f[j][1]-f[j][0]),最后再加上就好了。

f[i][1]=∑min(f[j][0],f[j][1],f[j][2])

f[i][2]=∑min(f[j][0])

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=10000+50;
 4 const int INF=0x7fffffff;
 5 int n,f[MAXN][3];
 6 vector<int> E[MAXN];
 7
 8 void init()
 9 {
10     scanf("%d",&n);
11     for (int i=0;i<n-1;i++)
12     {
13         int a,b;
14         scanf("%d%d",&a,&b);
15         E[a].push_back(b);
16         E[b].push_back(a);
17     }
18 }
19
20 void dp(int fr,int u)
21 {
22     f[u][0]=f[u][2]=0;
23     f[u][1]=1;
24     int delta=INF,flag=0;
25     for (int i=0;i<E[u].size();i++)
26     {
27         int v=E[u][i];
28         if (v==fr) continue;
29         dp(u,v);
30         if (f[v][1]<f[v][0]) flag=1;else delta=min(delta,f[v][1]-f[v][0]);
31         f[u][0]+=min(f[v][0],f[v][1]);
32         f[u][1]+=min(f[v][0],min(f[v][1],f[v][2]));
33         f[u][2]+=f[v][0];
34     }
35     if (flag==0) f[u][0]+=delta;
36     if (E[u].size()==1 && E[u][0]==fr)
37     {
38         f[u][0]=n;
39         f[u][1]=1;
40         f[u][2]=0;
41     }
42 }
43
44 void printans()
45 {
46     printf("%d",min(f[1][0],f[1][1]));
47 }
48
49 int main()
50 {
51     init();
52     dp(0,1);
53     printans();
54     return 0;
55 }
时间: 2024-10-05 06:57:43

【树形DP】BZOJ1596-[Usaco2008 Jan]电话网络的相关文章

bzoj1596[Usaco2008 Jan]电话网络*

bzoj1596[Usaco2008 Jan]电话网络 题意: 在一棵树中选最少的点建塔,使得每个点都有塔或相邻点有塔.n≤10000. 题解: 贪心.dfs时对于每个当前点,在dfs完它的所有子节点后如果它以及它的儿子以及它的父亲没塔,则在它父亲处建塔. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <queue> 5 #define inc(i

1596: [Usaco2008 Jan]电话网络

1596: [Usaco2008 Jan]电话网络 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 601  Solved: 265[Submit][Status][Discuss] Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号.所有的N块草地按1..N 顺次

【bzoj1596/Usaco2008 Jan】电话网络——dfs

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结尾的草地序列,并且序列中相邻的编号所代表的草地

BZOJ 1596: [Usaco2008 Jan]电话网络

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结尾的草地序列,并且序列中相邻的编号所代表的草地

【BZOJ】1596: [Usaco2008 Jan]电话网络

[算法]树上贪心 [题解] 因为一个点必须被覆盖,那么它如果没有被子树节点覆盖的话,就覆盖它的父节点. 从叶子开始贪心. 注意,如果它自己已经被选了就不需要选父节点了. #include<cstdio> #include<algorithm> #include<cstring> #include<cctype> using namespace std; const int maxn=10010; struct edge{int v,from;}e[maxn*

bzoj 1596: [Usaco2008 Jan]电话网络【贪心】

dfs,如果一个点的儿子.本身.父亲都没有塔,就在父亲上建一个 原理不明-- #include<iostream> #include<cstdio> using namespace std; const int N=10005; int n,h[N],cnt,ans; bool v[N]; struct qwe { int ne,to; }e[N<<1]; int read() { int r=0,f=1; char p=getchar(); while(p>'9

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

1596: [Usaco2008 Jan]电话网络 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1139  Solved: 534[Submit][Status][Discuss] Description Farmer John决定为他的所有奶牛都配备手机,以此鼓励她们互相交流.不过,为此FJ必须在奶牛们居住的N(1 <= N <= 10,000)块草地中选一些建上无线电通讯塔,来保证任意两块草地间都存在手机信号.所有的N块草地按1..N 顺

HDU-2196 Computer (树形DP)

最近在看树形DP,这题应该是树形DP的经典题了,写完以后还是有点感觉的.之后看了discuss可以用树分治来做,以后再试一试. 题目大意 找到带权树上离每个点的最远点.︿( ̄︶ ̄)︿ 题解: 对于每一个点的最远点,就是以这个点为根到所有叶子节点的最长距离.但是如果确定根的话,除了根节点外,只能找到每个节点(度数-1)个子树的最大值,剩下一个子树是该节点当前的父亲节点. 所以当前节点的最远点在当前节点子树的所有叶子节点以及父亲节点的最远点上(当父亲节点的最远点不在当前节点的子树上时), 如果父亲节

UVA-01220 Party at Hali-Bula (树形DP+map)

题目链接:https://vjudge.net/problem/UVA-1220 思路: 树形DP模板题,求最大人数很简单,难点在于如何判断最大人数的名单是否有不同的情况: 解决方法是用一个数组f[manx][2]记录该节点是否出场的情况,为真时代表有多种情况; 具体讨论: 当父节点的值加上某个子节点的值时,他的f的情况也和该子节点一样: 当某个节点dp(i, 0) == dp(i, 1), 则该节点以及它的父节点也一定有多种情况(父节点必定取其中之一). Code: 1 #include<bi