UVA 1218(树形DP)

题意:有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;
}

猜你喜欢

转载自blog.csdn.net/Dilly__dally/article/details/82289997