【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结尾的草地序列,并且序列中相邻的编号所代表的草地相邻。无线电通讯塔只能建在草地上,一座塔的服务范围为它所在的那块草地,以及与那块草地相邻的所有草地。 请你帮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也是如此。更形象一些,草地间的位置关系大体如下:
(或是其他类似的形状)
  4 2
  |   |
1--3--5

Sample Output

2


每次只考虑每个点与其父亲是否选择->当dfs到叶子的时候,选叶子肯定不如选叶子的父亲。

回溯的时候,如果此时这个点本身和其父亲都还没被选,那么就选父亲节点,原因同上,同时答案+1即可。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 const int N=1e4+10;
 5 struct node{int ne,to;}e[N*2];
 6 struct point{int num,id;}q[N];
 7 int n,first[N],tot=0;
 8 bool ok[N];
 9 bool cmp(point x,point y){return x.num>y.num;}
10 int read(){
11     int ans=0,f=1;char c=getchar();
12     while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
13     while(c>=‘0‘&&c<=‘9‘){ans=ans*10+c-48;c=getchar();}
14     return ans*f;
15 }
16 int ans=0;
17 void ins(int u,int v){e[++tot]=(node){first[u],v};first[u]=tot;}
18 void insert(int u,int v){ins(u,v);ins(v,u);}
19 void dfs(int x,int fa){
20     bool flag=0;
21     for(int i=first[x];i;i=e[i].ne){
22         int to=e[i].to;
23         if(to!=fa)dfs(to,x);
24         if(ok[to])flag=1;
25     }
26     if(!flag&&!ok[x]&&!ok[fa]){
27         ok[fa]=1;ans++;
28     }
29 }
30 int main(){
31     n=read();
32     for(int i=1;i<n;i++)
33         insert(read(),read());
34     dfs(1,0);
35     printf("%d",ans);
36     return 0;
37 }

bzoj1596

时间: 2024-08-25 00:21:04

【bzoj1596/Usaco2008 Jan】电话网络——dfs的相关文章

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 顺次

【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