wqs 二分
也叫带权二分,用于解决恰好选
二分的写法与函数凸的方向无关,而和问题是最大化还是最小化有关。
如果问题是最小化,那么当斜率增加,选一件物品的代价减小,显然我们会选择更多的物品。当斜率减少,选一件物品的代价增大,我们选的物品个数就会减少。也就是说,当当前选的物品个超过了限制,我们会增大二分的斜率。反之若当前选的物品还不够,则会减小当前二分的斜率。
如果问题是最大化,那么当斜率增加,选一件物品的代价减小,显然我们会选择更少的物品。当斜率减少,选一件物品的代价增大,我们选的物品个数就会增多。也就是说,当当前选的物品个超过了限制,我们会减小二分的斜率。反之若当前选的物品还不够,则会增大当前二分的斜率。
至于答案那个点和相邻的点共线的情况,我们可以每次 check 时让选的物品尽量少,然后就可以正常写。最后算答案的时候最终截距加上的应该是限制选的个数乘以最终斜率。
P5633 最小度限制生成树
有解容易做,判无解的时候可以利用 wqs 二分中的 check 函数,通过调整 check 的参数为
代码
#include <iostream>
#include <algorithm>
#include <cassert>
#define int long long
using namespace std;
const int inf = 10000000;
int n, m, s, K, d;
struct Edge {
int u, v, w, c;
} e[500005];
int dsu[100005];
int getf(int x) { return (dsu[x] == x ? x : (dsu[x] = getf(dsu[x]))); }
pair<int, int> chk(int x) {
for (int i = 1; i <= m; i++) e[i].w -= e[i].c * x;
sort(e + 1, e + m + 1, [](Edge a, Edge b) { return (a.w == b.w) ? (a.c > b.c) : (a.w < b.w); });
int ret = 0, cnt = 0;
for (int i = 1; i <= n; i++) dsu[i] = i;
int r = n - 1;
for (int i = 1; i <= m && r; i++) {
int u = getf(e[i].u), v = getf(e[i].v);
if (u != v)
--r, cnt += e[i].c, ret += e[i].w, dsu[u] = v;
}
for (int i = 1; i <= m; i++) e[i].w += e[i].c * x;
if (r != 0) {
cout << "Impossible\n";
exit(0);
}
return make_pair(ret, cnt);
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> s >> K;
for (int i = 1; i <= m; i++) cin >> e[i].u >> e[i].v >> e[i].w, e[i].c = (e[i].u == s || e[i].v == s), d += e[i].c;
int mn = chk(-inf).second, mx = chk(inf).second;
if (K < mn || mx < K) {
cout << "Impossible\n";
return 0;
}
int l = -inf, r = inf, mid, ans = 0;
while (l <= r) {
mid = (l + r) >> 1;
if (chk(mid).second >= K)
ans = mid, r = mid - 1;
else
l = mid + 1;
}
pair<int, int> tmp = chk(ans);
cout << chk(ans).first + K * ans << "\n";
return 0;
}
至多 / 至少 个
还是答案关于选的物品个数的函数是凸的,这个时候限制在平面上体现为一条竖线左 / 右的区域都可选。一般 wqs 二分只能做恰好
也可以在二分开始时将斜率的上 / 下界从
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现