• 【Uva 12128】Perfect Service


    Link:

    Description

    给你n个机器组成的一棵树,然后,让你在某些机器上安装服务器.
    要求,每个机器如果没有安装服务器,都要恰好和一个安装了服务器的机器连接.
    问你,最少要安装多少个服务器

    Solution

    比较常见的树形DP
    f[i][0]表示,i这个节点没装服务器,然后i这个节点没被儿子节点中的某一个控制,且儿子节点都已经符合要求的的最小服务器数.
    f[i][1]表示,i这个节点没装服务器,然后i这个节点被儿子节点中的某一个控制,且i以下的节点都已经符合要求的最小服务器个数.
    h[i]表示,i这个节点装了服务器,且以下的节点都已经符合要求的最小服务器个数.
    转移的时候
    (,ji)
    f[i][0]=f[j][1]
    h[i]=max(h[j],f[j][0])
    f[i][1]=f[j][1]+h[idx]f[idx][1]
    这里的idx是i的儿子节点中h的值最小的那个;
    表示要选一个儿子节点装上服务器,来控制这个i节点.
    对于叶子节点cnt
    f[cnt][0]=0,f[cnt][1] = INF,h[cnt] = 1;
    这里如果某个时刻,∑f[j][1] >= INF,则说明i节点会是倒数第二层的节点;
    则可以在最底层中的某一个装服务器,则直接把f[i][1]赋值为h[idx][1]就好;
    左边的∑符号里的东西可以省去了。
    加的时候可能会超int,所以大于INF了就变成INF

    NumberOf WA

    1

    Reviw

    这道题的数据挺水的。。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define ms(x,y) memset(x,y,sizeof x)
    #define Open() freopen("D:\rush.txt","r",stdin)
    #define Close() ios::sync_with_stdio(0)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 10000;
    const int INF = 0x3f3f3f3f;
    
    int n,f[N+100][2],h[N+100];
    
    vector <int> g[N+100];
    
    void limit(int &x){
        x = min(x,INF);
    }
    
    void dfs(int x,int fa){
        if (x!=1 && (int) g[x].size() == 1){
            f[x][0] = 0;
            f[x][1] = INF;
            h[x] = 1;
            return;
        }
        //f[i][0],没放服务器,没被控制,最小服务器个数
        //f[i][1],没放服务器,被控制了,最小服务器个数
        //h[i],放了服务器,且下面都被合法控制,最小服务器个数
        f[x][0] = f[x][1] = 0;
        h[x] = 1;
        int len = (int) g[x].size();
        int mi = INF,idx = 0;
        rep1(i,0,len-1){
            int y = g[x][i];
            if (y==fa) continue;
            dfs(y,x);
            if (h[y] < mi){
                mi = h[y];
                idx = y;
            }
            f[x][0] += f[y][1];
            limit(f[x][0]);
            f[x][1] += f[y][1];
            limit(f[x][1]);
            h[x] += min(f[y][0],h[y]);
            limit(h[x]);
        }
        if (f[x][1]>=INF){
            f[x][1] = h[idx];
        }else{
            f[x][1] -= f[idx][1];
            f[x][1] += h[idx];
        }
        limit(f[x][1]);
    }
    
    int main(){
        //Open();
        //Close();
        int t = 0;
        while (t==0){
            rep1(i,1,N) g[i].clear();
            scanf("%d",&n);
            rep1(i,1,n-1){
                int x,y;
                scanf("%d%d",&x,&y);
                g[x].pb(y),g[y].pb(x);
            }
            dfs(1,0);
            printf("%d
    ",min(h[1],f[1][1]));
            scanf("%d",&t);
            if (t==-1) break;
        }
        return 0;
    }
  • 相关阅读:
    python pandas里面的一些函数及用法
    Python enumerate() 函数
    论文笔记:EPTD模型/ Efficient and Privacy-Preserving Truth Discovery in Mobile Crowd Sensing Systems
    论文笔记:Adversarial Attacks and Defenses in Deep Learning 对抗训练部分
    一周入门Linux 基础篇 虚拟机快照
    一周入门Linux 基础篇 虚拟机克隆
    一周入门Linux 基础篇 网络连接的三种方式
    一周入门Linux 基础篇 安装vm和Centos
    B站考研网课推荐
    关于我
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626188.html
Copyright © 2020-2023  润新知