zoukankan      html  css  js  c++  java
  • ACWing 264 P4149 [IOI2011]Race

    说在前面

    还以为是什么神仙题...然后读了一下题发现很可做,但是有点卡。编号从0开始没注意,TLE+MLE一堆

    题意简述

    给一个(n)个节点的带权树和一个正整数(k),求一个简单路径,使得边权和等于(k),同时边数最少,输出最小边数。数据范围见题。

    简单口胡

    一看见题目就知道是点分治,然后考虑在点分治的基础上来维护最小值,发现在更新答案的时候,正常的点分治都是在前面的子树中找是否有能与它匹配起来和为(k)的。那么我们现在就改成:和为(k)中边数最小的。用(Min[d])代表边权和为(d)时当前的最短边个数。初始化除(Min[0] = 0)其余均为(+infty)。分别求出每个点到当前root的边权和和深度。
    对于更新答案:
    (ans = min(ans,dep[i] + Min[k - dis[i]]))
    对于更新(Min)
    (Min[dis[i]] = min(Min[dis[i]],dep[i]))

    同时在搜索时加上必要剪枝。

    # include <bits/stdc++.h>
    using namespace std;
    
    # define int long long
    
    const int N = 2e5 + 5;
    const int K = 1e6 + 5,inf = 1e10;
    
    int n,k;
    struct edge
    {
        int v,w;
        edge() {}
        edge(int _v,int _w) : v(_v),w(_w) {}
    };
    
    vector <edge> g[N];
    
    int siz[N],max_siz[N];
    int Min[K];
    // int Minn[K];
    bool del[N];
    int dep[N],dis[N];
    int root = 0,S;
    int cnt = 0;
    int tmp[N];
    int ans;
    
    void find_root(int x,int fa)
    {
        siz[x] = 1,max_siz[x] = 0;
        for(int i = 0; i < (int)g[x].size(); i++)
        {
            int v = g[x][i].v;
            if(v == fa || del[v]) continue;
            find_root(v,x);
            siz[x] += siz[v];
            if(siz[v] > max_siz[x]) max_siz[x] = siz[v];
        }
        max_siz[x] = max(max_siz[x],S - max_siz[x]); 
        if(max_siz[x] < max_siz[root]) root = x;
        return;
    }
    
    void Get_dis(int x,int fa)
    {
        if(dis[x] <= k && dep[x] <= ans) tmp[++cnt] = x;
        if(dep[x] >= ans) return;
        for(int i = 0; i < (int)g[x].size(); i++)
        {
            int v = g[x][i].v;
            if(v == fa || del[v]) continue;
            dis[v] = dis[x] + g[x][i].w;
            dep[v] = dep[x] + 1;
            Get_dis(v,x);
        }
        return;
    }
    
    void solve(int x)
    {
        queue <int> q;
        for(int i = 0; i < (int)g[x].size(); i++)
        {
            int v = g[x][i].v;
            if(del[v]) continue;
            dis[v] = g[x][i].w;
            dep[v] = 1;
            cnt = 0;
            Get_dis(v,x);
            for(int j = 1; j <= cnt; j++)
            {
                ans = min(ans,dep[tmp[j]] + Min[k - dis[tmp[j]]]);
            }
            for(int j = 1; j <= cnt; j++)
            {
                Min[dis[tmp[j]]] = min(Min[dis[tmp[j]]],dep[tmp[j]]); // Min[dis] = dep
                q.push(tmp[j]);
            }
        }
        while(!q.empty())
        {
            int top = q.front();
            Min[dis[top]] = inf;
            Min[k - dep[top]] = inf;
            q.pop();
        }
        return;
    }
    void dfs(int x)
    {
        // printf("dfs : x = %lld
    ",x);
        del[x] = 1;
        Min[0] = 0;
        dep[x] = 0;
        solve(x);
        // printf("YES:solve
    ");
        // for(int i = 1; i <= k; i++) Min[i] = inf;
        for(int i = 0; i < (int)g[x].size(); i++)
        {
            int v = g[x][i].v;
            if(del[v]) continue;
            max_siz[root = 0] = S = siz[v];
            find_root(v,0);
            find_root(root,0);
            dfs(root);
        }
        return;
    }
    
    signed main(void)
    {
        scanf("%lld%lld",&n,&k);
        for(int i = 1; i < n; i++)
        {
            int u,v,w;
            scanf("%lld%lld%lld",&u,&v,&w);
            ++u,++v;
            g[u].push_back(edge(v,w));
            g[v].push_back(edge(u,w));
        }
        max_siz[root = 0] = S = n;
        find_root(1,0);
        find_root(root,0);
        ans = inf * 10;
        for(int i = 1; i <= k; i++) Min[i] = inf;
        dfs(root);
        printf("%lld
    ",ans <= n ? ans : -1);
        return 0;
    }
    
  • 相关阅读:
    spring security几大核心组件
    什么是CSRF攻击?如何避免?
    MyBatis+Oracle实现主键自增长的几种常用方式
    fastjson在将Map<Integer, String>转换成JSON字符串时,出现中文乱码问题
    Layui我提交表单时,table.reload(),表格会请求2次,是为什么?
    Jquery+ajax模板
    HttpServletRequest和ServletRequest的区别
    java技术基础
    mysql数据库基础
    linux基础03
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/14766530.html
Copyright © 2011-2022 走看看