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;
}

猜你喜欢

转载自www.cnblogs.com/shuitiangong/p/12812189.html