loj#566. 「LibreOJ Round #10」yanQval 的生成树
\(\mu\) 取值即所选边权的中位数。
把每条边拆成两条(黑边和白边),边权分别为 \(\mu - w_i\) 和 \(w_i - \mu\),要求黑边和白边各选 \(\left\lfloor\dfrac{n-1}2\right\rfloor\) 条,求最大生成树。
可以直接 wqs 二分,时间复杂度 \(\mathcal O(nm \log w~\alpha(n))\)。
把所有边的边权同时加上一个 \(\mu\),则黑边边权为 \(2\mu - w_i\),白边边权为 \(w_i\),现在 \(\mu\) 的取值只会影响黑边的边权,wqs 二分的斜率 \(k\) 也只会影响黑边的边权,所以可以放到一起二分,时间复杂度 \(\mathcal O(m \log w~\alpha(n))\)。
一个值得注意的点是无论 \(n\) 的奇偶,取的黑边和白边的条数都是 \(\left\lfloor\dfrac{n-1}2\right\rfloor\)。
\(n\) 是奇数的时候显然,但 \(n\) 是偶数时,生成树上一定会有一条边无法确定颜色,否则会影响 wqs 二分中的答案,但本题下任一一棵 \(m\) 条边的生成树势必存在一棵与其离差相同的 \(m - 1\) 边的生成森林,所以直接做 \(n - 2\) 条边的最大生成森林即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
constexpr int N = 2e5 + 10, M = 5e5 + 10;
int n, m, eds;
ll res, ans;
struct Edge {
int u, v, w;
bool operator<(const Edge &rhs) const {return w > rhs.w;}
} e[M];
namespace DSU {
int fa[N], sz[N];
inline void init() {iota(fa + 1, fa + n + 1, 1); memset(sz + 1, 0, n << 2);}
inline int find(int x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
inline bool merge(int x, int y) {
int fx = find(x), fy = find(y);
if (fx == fy) return 0;
if (sz[fx] < sz[fy]) swap(fx, fy);
fa[fy] = fx, sz[fx] += sz[fy];
return 1;
}
}
bool check(int C) {
DSU::init();
int cnt = res = 0, wcnt = 0, l = 1, r = m;
while (l <= r) {
Edge cur; bool white = 0;
if (e[l].w > C - e[r].w) cur = e[l++];
else cur = e[r--], white = 1, cur.w = C - cur.w;
if (DSU::merge(cur.u, cur.v)) {
res += cur.w, wcnt += white;
if (++cnt == (eds << 1)) break;
}
}
res -= 1ll * eds * C;
return wcnt >= eds;
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
cin >> n >> m; eds = (n - 1) >> 1; if (!eds) {cout << 0; return 0;}
for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v >> e[i].w;
sort(e + 1, e + m + 1);
int l = 0, r = 1e9;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid - 1, ans = res;
else l = mid + 1;
}
cout << ans;
return 0;
}
作者:chy12321
出处:https://www.cnblogs.com/chy12321/p/18197537
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现