zoukankan      html  css  js  c++  java
  • UVA

    题目链接UVA - 1218 Perfect Service

    题意

    有n台电脑。互相以无根树的方式连接,现要将当中一部分电脑作为server,且要求每台电脑必须连接且仅仅能连接一台server(不包含作为server的电脑)。求最少须要多少台电脑作为server。

    思路

    典型的树形dp问题,那么我们来建立模型。
    d(u,0):u是server,孩子是不是server均可
    d(u,1):u不是server,u的父亲是server,u的孩子不能是server
    d(u,2):u不是server且u的父亲不是server,u的孩子必须有且仅有一个是server。

    那么显然的
    d(u,0) = 1 + Sum( Min(d(v,1), d(v,0)) ) |v是u的孩子
    d(u,1) = Sum(d(v,2))
    d(u,2)稍复杂些。由于仅仅能有一个孩子是server,所以须要遍历每一个孩子为server的情况,每一轮遍历都要同一时候计算其它全部孩子,须要O(N^2)的时间。
    显然这样会有非常多反复计算的情况,当然能够记忆化来加高速度,可是另一个更快的小技巧。由于d(u,1)和d(u,2)的唯一差别就是d(u,2)的孩子有一个server
    那么我们能够得出
    d(u,2) = Min(d(u,1)-d(v,2)+d(v,0)) |v是u的孩子
    仍是遍历设每一个孩子为server。每一轮的操作为O(1),整体为O(N)

    代码

    ps:由于d(u,2)初始要设为无穷大,就设了0x3f3f3f3f,结果改成N就好了,找了好久才找出问题出在这,由于这个wrong了好多遍,但还是不知道为什么会wrong,知道原因的道友请不吝指点。

    第一遍a的代码

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <cmath>
    #include <map>
    
    using namespace std;
    
    const int N = 10009;
    vector<int> g[N];
    int dp[N][3];
    
    void dfs(int u, int fa)
    {
        for(int i=0; i<g[u].size(); i++)
        {
            if(g[u][i] != fa)
                dfs(g[u][i], u);
        }
        dp[u][0] = 1;
        dp[u][1] = 0;
        dp[u][2] = N;
        for(int i=0; i<g[u].size(); i++)
        {
            if(g[u][i] != fa)
            {
                dp[u][0] += min(dp[g[u][i]][0], dp[g[u][i]][1]);
                dp[u][1] += dp[g[u][i]][2];
            }
        }
        bool f = true;
        for(int i=0; i<g[u].size(); i++)
        {
            if(g[u][i] != fa)
            {
                f = false;
                dp[u][2] = min(dp[u][2], dp[u][1]+dp[g[u][i]][0]-dp[g[u][i]][2]);
            }
        }
    }
    
    int main()
    {
        int n;
        while(cin>>n)
        {
            memset(dp, -1, sizeof(dp));
            int a, b;
            for(int i=1; i<n; i++)
            {
                cin>>a>>b;
                g[a].push_back(b);
                g[b].push_back(a);
            }
            dfs(1, -1);
            cout<<min(dp[1][0], dp[1][2])<<endl;
    
            cin>>a;
            if(a == -1)
                break;
            for(int i=1; i<=n; i++)
                g[i].clear();
        }
        return 0;
    }

    观摩大神代码后进行改动的精简版

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <vector>
    #include <cmath>
    #include <map>
    
    using namespace std;
    
    const int N = 10009;
    vector<int> g[N];
    int dp[N][3];
    
    void dfs(int u, int fa)
    {
        dp[u][0] = 1;
        dp[u][1] = 0;
        dp[u][2] = N;
        for(int i=0; i<g[u].size(); i++)
        {
            if(g[u][i] != fa)
            {
                dfs(g[u][i], u);
                dp[u][0] += min(dp[g[u][i]][0], dp[g[u][i]][1]);
                dp[u][1] += dp[g[u][i]][2];
            }
        }
    
        for(int i=0; i<g[u].size(); i++)
        {
            if(g[u][i] != fa)
                dp[u][2] = min(dp[u][2], dp[u][1]+dp[g[u][i]][0]-dp[g[u][i]][2]);
        }
    }
    
    int main()
    {
        int n;
        while(cin>>n)
        {
            int a, b;
            for(int i=1; i<n; i++)
            {
                cin>>a>>b;
                g[a].push_back(b);
                g[b].push_back(a);
            }
            dfs(1, -1);
            cout<<min(dp[1][0], dp[1][2])<<endl;
    
            cin>>a;
            if(a == -1)
                break;
            for(int i=1; i<=n; i++)
                g[i].clear();
        }
        return 0;
    }
  • 相关阅读:
    匿名变量
    Vue父子组件传值与非父子传值
    TCP三次握手分析
    @media screen 响应式布局
    H5新增多媒体标签
    npm+node+vue配置一套带走
    vue+echarts全国疫情地图
    js本地时间格式化
    vue iview分页
    Vue打包后访问静态资源路径问题
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/7308925.html
Copyright © 2011-2022 走看看