• Uva 1218 完美的服务


    题目链接:https://uva.onlinejudge.org/external/12/1218.pdf

    题意:

    一个网络,选出一些点做服务器,使满足一些条件,求服务器最少数量。条件是,每个计算机恰有一台服务器相连。

    分析:

    对于每个节点,都有3种状态,1、他是服务器 d(u,0),2、他不是服务器,但是父亲是的 d(u,1),如果他父亲是服务器,将影响他的接下来的决策。3、他不是服务器,父亲也不是服务器 d(u,2);

    那么: 

    d(u,0) = sum{max{d(v,0),d(v,1)}};

    d(u,1) = sum{d(v,2)};

    d(u,2) 子节点恰有一台是服务器,可以利用 上面的求出, d(u,2) = min{d(u,1)-d(v,2)+d(v,0)};

    建树时,可以以任一点为根。

    #include <bits/stdc++.h>
    using namespace std;
    
    #define maxn 10005
    #define INF 0x3f3f3f3f
    
    int n;
    vector<int> G[maxn],vertices;
    int p[maxn],d[maxn][3];
    
    //建树
    void dfs(int u,int fa) {
        vertices.push_back(u);
        p[u] = fa;
        for(int i=0;i<G[u].size();i++) {
            int v = G[u][i];
            if(v!=fa)
                dfs(v,u);
        }
    }
    
    
    int main()
    {
        while(scanf("%d",&n),n!=-1) {
    
            for(int i=0;i<n;i++)
                G[i].clear();
    
            for(int i = 0;i<n-1;i++) {
                int u,v;
                scanf("%d%d",&u,&v);
                u--;
                v--;
                G[u].push_back(v);
                G[v].push_back(u);
            }
    
            vertices.clear();
            dfs(0,-1);
            memset(d,0,sizeof(d));
    
            for(int i=vertices.size()-1;i>=0;i--) {
                int u = vertices[i];
                d[u][0] = 1;
                d[u][1] = 0;
                for(int j=0;j<G[u].size();j++) {
                    int v = G[u][j];
                    if(v==p[u]) continue;
                    d[u][0] +=min(d[v][0],d[v][1]);
                    d[u][1] +=d[v][2];
                    if(d[u][0]>INF) d[u][0] = INF;
                    if(d[u][1]>INF) d[u][1] = INF;
                }
                d[u][2] = INF;
    
                for(int j=0;j<G[u].size();j++) {
                    int v = G[u][j];
                    if(v==p[u]) continue;
                    d[u][2] = min(d[u][2],d[u][1]-d[v][2]+d[v][0]);
                }
    
            }
            printf("%d
    ",min(d[0][0],d[0][2]));
            scanf("%d",&n);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    iOS 8以后 定位手动授权问题
    IOS int NSInteger NSNumber区分
    Java基础知识(JAVA集合框架之List与Set)
    Java基础知识(JAVA基本数据类型包装类)
    Java基础知识(JAVA中String、StringBuffer、StringBuilder类的区别)
    Java基础知识(重载和覆盖)
    Java基础知识(抽象类和接口)
    host文件
    天猫页面显示错位
    专题8:javascript函数详解
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6004069.html
Copyright © 2020-2023  润新知