[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] << " ";
}
}