79: cf 444E 并查集+思维
$des$
$sol$
把边从小到大排序,枚举每条边作为答案,然后把两个点合并,
判断每条边是否可以作为答案时,
$cnt_i$ 表示节点 $i$ 已经合并的 $x$ 之和
$size_i$ 表示已经合并的节点的个数
$sum = \sum x$
将 $a$ 与外面的点合并时
判断条件 $size_a <= sum - cnt_a$
并查集维护。
$code$
#include <bits/stdc++.h> using namespace std; #define Rep(i, a, b) for(int i = a; i <= b; i ++) #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } const int N = 1e5 + 10; int n, Cnt[N], Size[N], fa[N], Sum; struct Node { int u, v, w; bool operator < (Node a) const { return this->w < a.w; } } G[N]; bool Ok; int Get(int x) { return fa[x] == x ? x : fa[x] = Get(fa[x]); } void Merge(int x, int y) { x = Get(x), y = Get(y); Size[x] += Size[y]; Cnt[x] += Cnt[y]; fa[y] = x; if(Size[x] > Sum - Cnt[x]) Ok = 0; } int main() { n = read(); Rep(i, 1, n - 1) G[i] = (Node) { read(), read(), read() }; sort(G + 1, G + n); Rep(i, 1, n) Cnt[i] = read(), Sum += Cnt[i]; Rep(i, 1, n) fa[i] = i, Size[i] = 1; int Answer = 0; Ok = 1; Rep(i, 1, n - 1) { if(Ok) Answer = G[i].w; Merge(G[i].u, G[i].v); } cout << Answer; return 0; }