• T


    T - zxa and leaf

     HDU - 5682 

    题目大意是:给你一颗树,这棵树有些节点已经设置了它的美丽值,然后剩下一些节点需要我们设置美丽值。

    一条边的丑陋程度等于被定义为由这个边缘连接的两个节点之间的美丽水平的绝对差异

    一棵树的丑陋程度则是边的丑陋程度的最大值。

    这个题目应该是二分这个丑陋值。

    然后dfs来判断这个丑陋值是不是合理。

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <map>
    #include <queue>
    #include <vector>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    const int maxn = 1e5 + 10;
    vector<int>G[maxn];
    ll lc[maxn], rc[maxn], el[maxn], er[maxn];
    
    bool dfs(int u,int pre,int x)
    {
        //printf("u=%d pre=%d x=%d
    ", u, pre, x);
        int flag = 1;
        for(int i=0;i<G[u].size();i++)
        {
            int v = G[u][i];
            if (v == pre) continue;
            if (lc[v] == 0 && rc[v] == 0) {
                lc[v] = max(1ll * 0, lc[u] - x);
                rc[v] = rc[u] + x;
            }
            else {
                ll val = lc[v];
                if ((val <= rc[u] && val >= lc[u]))
                {
                    rc[u] = min(rc[u], val + x);
                    lc[u] = max(val - x, lc[u]);
                }
                else if (abs(val - lc[u]) <= x || abs(val - rc[u]) <= x)
                {
                    if (val >= rc[u]) lc[u] = max(lc[u], val - x);
                    if (val <= lc[u]) rc[u] = min(rc[u], val + x);
                    if (lc[u] > rc[u]) return false;
                }
                else return false;
            }
            //printf("lc[%d]=%lld rc[%d]=%lld
    ", v, lc[v], v, rc[v]);
            if (dfs(v, u, x) == 0) flag = 0;
        }
        return flag;
    }
    
    
    
    int main()
    {
        int t;
        scanf("%d", &t);
        while(t--)
        {
            int n, k;
            memset(el, 0, sizeof(el));
            memset(er, 0, sizeof(er));
            scanf("%d%d", &n, &k);
            for (int i = 0; i <= n; i++) G[i].clear();
            for (int i = 1; i < n; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                G[u].push_back(v);
                G[v].push_back(u);
            }
            int mark = 0;
            for (int i = 1; i <= k; i++) {
                int u, w;
                scanf("%d%d", &u, &w);
                mark = u;
                el[u] = er[u] = w;
            }
            //printf("mark=%d
    ", mark);
            int l = 0, r = 1e9, ans = 0;
            while(l<=r)
            {
                memcpy(lc, el, sizeof(el));
                memcpy(rc, er, sizeof(er));
                int mid = (l + r) >> 1;
                if (dfs(mark,-1,mid)) ans = mid, r = mid - 1;
                else l = mid + 1;
                //printf("l=%d r=%d mid=%d ans=%d
    
    ", l, r, mid, ans);
            }
            printf("%d
    ", ans);
        }
    }
    /*
     2
    10 4
    7 2
    1 5
    10 2
    1 9
    5 7
    1 8
    3 5
    4 7
    6 8
    9 39
    6 9
    2 26
    4 10
     */
    View Code
  • 相关阅读:
    virtual方法和abstract方法的使用(轉載)
    C# 如何寫入cookie
    Literal的一般用法,与Label对比 MSDN上的解释
    With temp as---sql语句用法 转
    GridView __DataKey 使用
    .net里radiobutton 两个怎么才能让他只选择一个
    Server.Transfer()与Response.Redirect()区别
    OnInit 事件
    ajax中Sys.WebForms.PageRequestManager的事件激发顺序
    Linux CentOS 查看某个进程打开的文件(文件描述符)
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11391537.html
Copyright © 2020-2023  润新知