题意:有n台机器形成树状结构。要求在其中一些机器上安装服务器,使得每台不是服务器的计算机恰好和一台服务器计算机相邻。求服务器的最少数量。
思路:dp[u][0]表示u是服务器,u的孩子是或不是都可以。dp[u][1]表示u不是,u的父亲是,所以u的孩子都不是。dp[u][2]表示u不是,u的父亲也不是,所以u的孩子有且仅有一个是服务器。
dp[u][0]=1+sum(min(dp[v][1],dp[v][0]));
dp[u][1]=sum(dp[v][2]);
dp[u][2]=min(dp[u][2],dp[v1][2]+dp[v2][2]+……+dp[v][0])=min(dp[u][2],dp[u][1]-dp[v][2]+dp[v][0])
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=10005;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
vector<int> v[maxn];
int dp[maxn][3];
void dfs(int u,int fa)
{
dp[u][0]=1;
dp[u][1]=0;
dp[u][2]=maxn;
if(v[u].size()==1&&fa!=-1)
return ;
for(int i=0;i<v[u].size();i++)
{
int c=v[u][i];
if(c==fa)
continue;
dfs(c,u);
dp[u][0]+=min(dp[c][0],dp[c][1]);
dp[u][1]+=dp[c][2];
}
for(int i=0;i<v[u].size();i++)
{
int c=v[u][i];
if(c==fa)
continue;
dp[u][2]=min(dp[u][2],dp[u][1]-dp[c][2]+dp[c][0]);
}
}
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int n;
while(cin>>n)
{
for(int i=0;i<maxn;i++)
{
v[i].clear();
}
int a,b;
for(int i=0;i<n-1;i++)
{
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(1,-1);
cin>>a;
cout<<min(dp[1][0],dp[1][2])<<endl;
if(a==-1)
break;
}
return 0;
}