P5934 [清华集训2012]最小生成树
题意
给定一张无向有权图和一条额外的边,问最少删除多少条边,可以使得这条额外的边即有可能出现在这张图的最小生成树中,也有可能出现在最大生成树中。
解法
考虑用 Kruskal 求最小生成树时,对于额外的这条边
最大生成树同理,答案是两个最小割之和。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int u[N], v[N], w[N], cur[N], d[N];
int n, m, s, t, L, ans = 0;
int e[N], c[N], h[N], ne[N], idx;
void add(int U, int V, int W)
{
e[idx] = V, c[idx] = W, ne[idx] = h[U], h[U] = idx++;
e[idx] = U, c[idx] = 0, ne[idx] = h[V], h[V] = idx++;
}
int bfs()
{
for (int i = 1; i <= n; i++) d[i] = -1;
cur[s] = h[s];
d[s] = 0;
queue<int> q;
q.push(s);
while (q.size())
{
int u = q.front();
q.pop();
for (int i = h[u]; ~i; i = ne[i])
{
int j = e[i];
if (d[j] == -1 && c[i] > 0)
{
d[j] = d[u] + 1;
cur[j] = h[j];
if (j == t) return 1;
q.push(j);
}
}
}
return 0;
}
int dfs(int u, int lim)
{
if (u == t) return lim;
int flow = 0;
for (int i = cur[u]; ~i && flow < lim; i = ne[i])
{
cur[u] = i;
int j = e[i];
if (d[j] == d[u] + 1 && c[i] > 0)
{
int t = dfs(j, min(c[i], lim - flow));
if (t == 0) d[j] = -1;
flow += t;
c[i] -= t, c[i ^ 1] += t;
}
}
return flow;
}
int dinic()
{
int ret = 0, f;
while (bfs())
{
while (f = dfs(s, (int)2e9)) ret += f;
}
return ret;
}
signed main()
{
memset(h, -1, sizeof h);
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= m; i++)
{
scanf("%lld%lld%lld", &u[i], &v[i], &w[i]);
}
scanf("%lld%lld%lld", &s, &t, &L);
for (int i = 1; i <= m; i++)
{
if (w[i] < L)
{
add(u[i], v[i], 1);
add(v[i], u[i], 1);
}
}
ans = dinic();
memset(h, -1, sizeof h);
idx = 0;
for (int i = 1; i <= m; i++)
{
if (w[i] > L)
{
add(u[i], v[i], 1);
add(v[i], u[i], 1);
}
}
ans += dinic();
printf("%lld\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现