zoukankan      html  css  js  c++  java
  • DFS——hdu5682zxa and leaf

    一、题目回顾

    题目链接:zxa and leaf

    Sample Input
    2
    3 2
    1 2
    1 3
    2 4
    3 9
    6 2
    1 2
    1 3
    1 4
    2 5
    2 6
    3 6
    5 9
     
    Sample Output
    3
    1
     
    Hint

    If you need a larger stack size, please use #pragma comment(linker, "/STACK:102400000,102400000") and submit your solution using C++.

    题意:一棵树n个点,其中有一些点已经有权值,现在给剩下的点安排权值,使得树中相邻两点的之差绝对值的最大值最小。

    二、解题思路

    • 二分+树形dp(也可以二分+dfs)

    思路:如果我们首先就想到了二分,那后面很好想了。。

    直接二分答案,之后check中,我们随便取1个点为根节点,然后从下向上按拓扑序做树型dp。设SL[u]和SR[u]表示节点u能填的数字的范围

    我们从下往上,然后只要判断是否有交集,即有解,我们就能知道当前答案是否可以使用了。

    三、代码

    #include <map>
    #include <set>
    #include <cmath>
    #include <ctime>
    #include <stack>
    #include <queue>
    #include <cstdio>
    #include <cctype>
    #include <bitset>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #define fuck(x) cout<<"["<<x<<"]";
    #define FIN freopen("input.txt","r",stdin);
    #define FOUT freopen("output.txt","w+",stdout);
    #pragma comment(linker, "/STACK:102400000,102400000")
    using namespace std;
    typedef long long LL;
    typedef pair<int, int> PII;
    
    const int MX = 1e5 + 5;
    const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    
    struct Edge {
        int nxt, v;
    } E[MX];
    int Head[MX], erear;
    void edge_init() {
        erear = 0;
        memset(Head, -1, sizeof(Head));
    }
    void edge_add(int u, int v) {
        E[erear].v = v;
        E[erear].nxt = Head[u];
        Head[u] = erear++;
    }
    
    int is[MX], val[MX];
    LL SL[MX], SR[MX];
    
    bool DFS(int u, int f, int x) {
        if(is[u]) SL[u]  = SR[u] = val[u];
        else SL[u] = -INF, SR[u] = INF;
        for(int i = Head[u]; ~i; i = E[i].nxt) {
            int v = E[i].v;
            if(v == f) continue;
            if(!DFS(v, u, x)) return false;
            if(SL[v] != INF) SL[u] = max(SL[u], SL[v] - x);
            if(SR[v] != INF) SR[u] = min(SR[u], SR[v] + x);
        }
        if(SL[u] > SR[u]) return false;
        return true;
    }
    int solve() {
        int l = 0, r = 1e9, m;
        while(l <= r) {
            m = (l + r) >> 1;
            if(DFS(1, -1, m)) r = m - 1;
            else l = m + 1;
        }
        return r + 1;
    }
    
    int main() {
        int T, n, k; //FIN;
        scanf("%d", &T);
        while(T--) {
            edge_init();
            scanf("%d%d", &n, &k);
            for(int i = 1; i <= n; i++) is[i] = 0;
            for(int i = 1; i <= n - 1; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
                edge_add(u, v); edge_add(v, u);
            }
            for(int i = 1; i <= k; i++) {
                int u, w;
                scanf("%d%d", &u, &w);
                is[u] = 1; val[u] = w;
            }
            printf("%d
    ", solve());
        }
        return 0;
    }
    
  • 相关阅读:
    【原创】FltGetFileNameInformation蓝屏分析
    【原创】调用系统函数里面蓝屏例子
    【原创】FltSendMessage蓝屏分析
    RES协议和断网访问URL出现的错误页面
    绕过本机DNS缓存
    异步机制
    异步机制
    异步机制
    异步机制
    异步机制
  • 原文地址:https://www.cnblogs.com/xzxl/p/7310294.html
Copyright © 2011-2022 走看看