Codeforces 1296F Berland Beauty(思维,图)
题目大意
给一棵无根树以及\(m\)个限制条件,表示从一个结点到另外一个结点走过的最小权值,求每条边的赋值方案。
具体实现
对没有访问过的边随便赋值就行了。如果是访问过的边,就让它们的权值比限制条件小的等于限制条件的值。检查是否符合条件也很简单,经过之前的操作路径上的值至少是大于等于限定的值的,所以如果这条路径的最小值大于限定的值,肯定是不符合条件的。
代码
const int maxn = 5e3+10;
struct EDGE {
int u, v, w;
EDGE (int a=0, int b=0, int c=0) : u(a), v(b), w(c) {}
} lmt[maxn];
vector<P> e[maxn];
int f[maxn]; bool ok;
bool dfs(int p, int u, int goal, int w) {
if (u == goal) return true;
for (auto v : e[u])
if (v.first != p && dfs(u, v.first, goal, w)) {
f[v.second] = max(f[v.second], w);
if (f[v.second]==w) ok = true;
return true;
}
return false;
}
int main(void) {
int n; scanf("%d", &n);
for (int i = 0, u, v; i<n-1; ++i) {
scanf("%d%d", &u,&v);
e[u].emplace_back(v, i);
e[v].emplace_back(u, i);
f[i] = 1;
}
int m; scanf("%d", &m);
for (int i = 0, u, v, w; i<m; ++i) {
scanf("%d%d%d", &u, &v, &w);
lmt[i] = EDGE(u, v, w);
dfs(0, u, v, w);
}
for (int i = 0; i<m; ++i) {
ok = false;
dfs(0, lmt[i].u, lmt[i].v, lmt[i].w);
if (!ok) {
printf("-1\n");
return 0;
}
}
for (int i = 0; i<n-1; ++i) printf(i==n-2?"%d\n":"%d ", f[i]);
return 0;
}