[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] << " ";
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/14447024.html