弱化版将军令;//然而这里并不讲将军令的做法而是讲另一种dp做法。
dp一下;
dp[i][0] =表示i子树内所有草地全被覆盖,但是点i没有信号塔所需要的最小信号塔;
dp[i][1] =表示i子树内所有草地全被覆盖,点i有信号塔所需要的最小信号塔;
dp[i][2]=表示i子树内除了i所有草地全被覆盖,
dp[i][1]可以由他的儿子v 的所有状态更新,初值为1,表示i位置有塔;
dp[i][2]可以由他的儿子v 的dp[v][1],dp[v][0]状态更新;
dp[i][0]由dp[i][2],枚举每个儿子,如果dp[i][2],是由dp[v][0]更新而来,那么dp[i][0]=dp[i][2]+1;
#include<bits/stdc++.h>
using namespace std;
int n,tp,nex[200005],h[100005],tov[200005];
int dp[100005][3];
void add(int x,int y)
{
tp++;
nex[tp] = h[x];
h[x] = tp;
tov[tp] = y;
}
void dfs(int x,int fa)
{
dp[x][0] = 1e9,dp[x][1] = 1,dp[x][2] = 0;
for(int i = h[x]; i ; i = nex[i])
{
int v = tov[i];
if(v == fa)
{
continue;
}
dfs(v,x);
dp[x][1] += min(min(dp[v][1],dp[v][0]),dp[v][2]);
dp[x][2] += min(dp[v][1],dp[v][0]);
}
for(int i = h[x]; i; i = nex[i])
{
int v = tov[i];
if(v == fa)
{
continue;
}
dp[x][0] = min( dp[x][0], dp[v][1] - min(dp[v][1],dp[v][2]) + dp[x][2] );
}
}
int main()
{
freopen("CP.in", "r", stdin);
freopen("CP.out", "w", stdout);
cin >> n;
for(int i = 1; i <= n-1; i++)
{
int x,y;
scanf("%d%d", &x, &y);
add(x,y);
add(y,x);
}
dfs(1,1);
cout << min(dp[1][0],dp[1][1]);
return 0;
}