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,j,k) for(int i=j;i<=k;i++)
 6 #define maxn 10010
 7 using namespace std;
 8
 9 inline int read(){
10     char ch=getchar(); int f=1,x=0;
11     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();}
12     while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar();
13     return f*x;
14 }
15 struct e{int t,n;}es[2*maxn]; int ess,g[maxn];
16 void pe(int f,int t){
17     es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess;
18 }
19 int n,ans; bool cov[maxn];
20 void dfs(int x,int fa){
21     bool f=0;
22     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa){
23         dfs(es[i].t,x); if(cov[es[i].t])f=1;
24     }
25     if(!f&&!cov[x]&&!cov[fa])ans++,cov[fa]=1;
26 }
27 int main(){
28     n=read(); inc(i,1,n-1){int x=read(),y=read(); pe(x,y);} dfs(1,0); printf("%d",ans); return 0;
29 }

20161108

时间: 2024-08-02 22:26:43

bzoj1596[Usaco2008 Jan]电话网络*的相关文章

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]电话网络

[算法]树上贪心 [题解] 因为一个点必须被覆盖,那么它如果没有被子树节点覆盖的话,就覆盖它的父节点. 从叶子开始贪心. 注意,如果它自己已经被选了就不需要选父节点了. #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]电话网络

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]电话网络【贪心】

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

[bzoj1612][Usaco2008 Jan]Cow Contest奶牛的比赛_dfs

Cow Contest奶牛的比赛 bzoj-1612 Usaco-2008 Jan 题目大意:题目链接. 注释:略. 想法: 我们对于每个点dfs,看一下比这个点大的点加上比这个点小的点是否是n-1即可. 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N

BZOJ1595 [Usaco2008 Jan]人工湖

直接模拟...从最低的开始向两边拓展= = 1 /************************************************************** 2 Problem: 1595 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:328 ms 7 Memory:3932 kb 8 ***************************************************************

[BZOJ1594] [Usaco2008 Jan]猜数游戏(二分 + 并查集)

传送门 题中重要信息,每堆草的数量都不一样. 可以思考一下,什么情况下才会出现矛盾. 1.如果两个区间的最小值一样,但是这两个区间没有交集,那么就出现矛盾. 2.如果两个区间的最小值一样,并且这两个区间有交集,那么这个最小值一定在交集中,但是如果这个交集被某个最小值较大的区间,或是一些最小值较大的区间的并集包含,那么也是矛盾的. 可以二分答案,将这些区间按照最小值从大到小排序,然后可以用线段树维护,也可以用并查集来搞. 下面是用并查集来搞的. 每到一个区间,可以将[l,r]中的f变成r+1,如果

【树形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