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最少建立无线电通讯塔的数目
#include<stdio.h>
#include<iostream>
using namespace std;
const int N=10005;
int n,i,x,y,f[N][3];
int tot,head[N],Next[N<<1],to[N<<1];
void add(int x,int y)
{
tot++;
to[tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
void dfs(int x,int pre)
{
f[x][0]=0;
f[x][1]=1;
f[x][2]=1000000;
int i,y,s=0;
for(i=head[x];i!=-1;i=Next[i])
if(to[i]!=pre) dfs(to[i],x);
for(i=head[x];i!=-1;i=Next[i])
{
y=to[i];
if(y==pre) continue;
f[x][1]+=min(f[y][2],min(f[y][1],f[y][0]));
f[x][0]+=min(f[y][2],f[y][1]);
s+=min(f[y][2],f[y][1]);
}
for(i=head[x];i!=-1;i=Next[i])
{
y=to[i];
if(y==pre) continue;
f[x][2]=min(f[x][2],f[y][1]+s-min(f[y][2],f[y][1]));
}
}
int main()
{
scanf("%d",&n);
for(i=1;i<=n;i++) head[i]=-1;
for(i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
cout<<min(f[1][2],f[1][1]);
return 0;
}