• [CF1296F] Berland Beauty


    [CF1296F] Berland Beauty - 构造

    Description

    给你一颗大小为 (n) 的无根树,树边的边权尚未确定,现在你从 (m) 个人中得知在 ((u,v)) 这条路径(最短路径)上的最小边权为 (w),请你构造一种方案满足这 (m) 个人的条件,如果不存在,请输出 (-1)

    Solution

    把它们当作 m 次 max 操作,每次将 (u,v) 上的所有边对 w 取 max

    如果这样做不行,那么可以说明是无解的

    最后扫一遍判断一下

    这种比较暴力的树上操作不太常写,考虑怎么写得优雅一点

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    void dfs(const vector<vector<int>> &g,
             vector<int> &dep,
             vector<int> &fa,
             int p)
    {
        for (auto q : g[p])
        {
            if (q == fa[p])
                continue;
            dep[q] = dep[p] + 1;
            fa[q] = p;
            dfs(g, dep, fa, q);
        }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int n, m;
    
        cin >> n;
        vector<vector<int>> g(n + 2);
        vector<pair<int, int>> edge;
        for (int i = 1; i < n; i++)
        {
            int u, v;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
            edge.push_back({u, v});
        }
    
        vector<int> dep(n + 2);
        vector<int> fa(n + 2);
    
        dfs(g, dep, fa, 1);
    
        vector<int> a(n + 2, 1);
        vector<tuple<int, int, int>> limit;
        cin >> m;
        for (int i = 1; i <= m; i++)
        {
            int u, v, w;
            cin >> u >> v >> w;
            limit.push_back({u, v, w});
            while (u - v)
            {
                if (dep[u] < dep[v])
                    swap(u, v);
                a[u] = max(a[u], w);
                u = fa[u];
            }
        }
    
        for (auto [u, v, w] : limit)
        {
            int tmp = 1e18;
            while (u - v)
            {
                if (dep[u] < dep[v])
                    swap(u, v);
                tmp = min(tmp, a[u]);
                u = fa[u];
            }
            if (w - tmp)
            {
                cout << -1;
                return 0;
            }
        }
    
        for (auto [u, v] : edge)
        {
            if (dep[u] < dep[v])
                swap(u, v);
            cout << a[u] << " ";
        }
    }
    
  • 相关阅读:
    PHP 消息队列
    Nginx 设置负载均衡
    Nginx 服务器搭建
    PHP 获取文件扩展名的五种方式
    高并发和大流量解决方案
    <面试> PHP 常见算法
    Mysql 预查询处理 事务机制
    Linux定时任务 结合PHP实现实时监控
    Swoole 结合TP5搭建文字直播平台
    <记录> PHP Redis操作类
  • 原文地址:https://www.cnblogs.com/mollnn/p/14447024.html
Copyright © 2020-2023  润新知