Description

树上每条边有一个权值 \(x_i\) 未知,给定 \(m\) 个限制每个限制描述了路径 \(p,q\) 上的最小值,构造权值方案或者判定无解。

Solution

贪心,对于每个限制,路径上所有点暴力取 max 即可。最后再扫一遍检查是否所有条件都被满足。

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

int n, m, t1, t2, t3, t4;
int a[N], b[N], c[N], d[N];
vector<int> g[N];
int ans[N];
int vis[N];
vector<int> vec;
int target;
vector<pair<int, int>> edges;

void dfs0(int p)
{
    vis[p] = 1;
    for (int q : g[p])
    {
        if (vis[q] == 0)
        {
            d[q] = d[p] + 1;
            dfs0(q);
        }
    }
}

void update(int p, int q, int val)
{
    // cout << "upd " << p << " " << q << " = " << val << endl;
    int x = d[p] < d[q] ? q : p;
    // cout << " x=" << x << endl;
    ans[x] = max(ans[x], val);
}

int query(int p, int q)
{
    int x = d[p] < d[q] ? q : p;
    return ans[x];
}

bool dfs(int p)
{
    vis[p] = 1;
    vec.push_back(p);
    if (p == target)
    {
        return true;
    }
    for (int q : g[p])
    {
        if (vis[q] == 0)
        {
            if (dfs(q))
                return true;
        }
    }
    if (vec.size())
        vec.pop_back();
    return false;
}

void solve(int p, int q, int val)
{
    memset(vis, 0, sizeof vis);
    vec.clear();
    target = q;
    dfs(p);
    for (int i = 1; i < vec.size(); i++)
    {
        int x = vec[i - 1], y = vec[i];
        update(x, y, val);
    }
}

bool check(int p, int q, int val)
{
    memset(vis, 0, sizeof vis);
    vec.clear();
    target = q;
    dfs(p);
    for (int i = 1; i < vec.size(); i++)
    {
        int x = vec[i - 1], y = vec[i];
        if (query(x, y) == val)
            return true;
    }
    return false;
}

signed main()
{
    ios::sync_with_stdio(false);

    cin >> n;
    for (int i = 1; i < n; i++)
    {
        cin >> t1 >> t2;
        g[t1].push_back(t2);
        g[t2].push_back(t1);
        edges.push_back({t1, t2});
    }

    dfs0(1);

    for (int i = 1; i <= n; i++)
        ans[i] = 1;

    cin >> m;
    for (int i = 1; i <= m; i++)
    {
        cin >> a[i] >> b[i] >> c[i];
    }

    for (int i = 1; i <= m; i++)
    {
        solve(a[i], b[i], c[i]);
    }

    int flag = 1;
    for (int i = 1; i <= m; i++)
    {
        if (check(a[i], b[i], c[i]) == 0)
        {
            cout << -1;
            return 0;
        }
    }

    for (auto edge : edges)
    {
        int u = edge.first, v = edge.second;
        cout << query(u, v) << " ";
    }
}

相关文章: