BZOJ 2521: [Shoi2010]最小生成树(最小割)
题意
对于某一条无向图中的指定边 \((a, b)\) , 求出至少需要多少次操作。可以保证 \((a, b)\) 边在这个无向图的最小生成树中.
一次操作指: 先选择一条图中的边 \((u, v)\), 再把图中除了这条边以外的边, 每一条的权值都减少 \(1\) .
\(n \le 500, m \le 800, 1 \le w_i < 10^6\)
题解
给除了一条边的所有边权 \(-1\) ,相当于给这条边的边权 \(+1\) 。
利用生成树的结论,一条边 \(u \to v\) (权值 \(w\) )若要必定存在于生成树中,那么 \(u \to v\) 所有路径上存在一条边的边权都不能大于 \(w\) 。
那么我们令这些边的权值为 \(w_i' = \max \{w(a,b)-w_i+1, 0\}\) 。
然后从 \(a \to b\) 跑一遍最小割就行了。
这样为什么是对的呢?因为只要割掉了所有可行的边,那么就把 \(a, b\) 分成两个连通子图,要连上这两个子图的最小代价就是这个最小割的答案。
总结
对于一些奇怪数据范围的题,可以向网络流上想。
代码
注意连边的时候,需要把正向边和反向边的流量都置为正,这是因为整个图是无向的。
#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
using namespace std;
inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}
inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x * fh;
}
void File() {
#ifdef zjp_shadow
freopen ("2521.in", "r", stdin);
freopen ("2521.out", "w", stdout);
#endif
}
const int N = 510, M = 810 * 2, inf = 0x3f3f3f3f;
int n, m, id;
namespace Dinic {
int Head[N], Next[M], to[M], cap[M], e = 1;
inline void add_edge(int u, int v, int flow) { to[++ e] = v; Next[e] = Head[u]; Head[u] = e; cap[e] = flow; }
inline void Add(int u, int v, int flow) { add_edge(u, v, flow); add_edge(v, u, flow); }
int S, T, dis[N];
bool Bfs() {
queue<int> Q; Set(dis, 0); Q.push(S); dis[S] = 1;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int i = Head[u]; i; i = Next[i]) if (cap[i]) {
int v = to[i]; if (!dis[v]) { dis[v] = dis[u] + 1; if (v == T) return true; Q.push(v); }
}
}
return false;
}
int cur[N];
int Dfs(int u, int flow) {
if (u == T || !flow) return flow;
int res = 0, f;
for (int &i = cur[u]; i; i = Next[i]) if (cap[i]) {
int v = to[i]; if (dis[v] != dis[u] + 1) continue ;
if ((f = Dfs(v, min(flow, cap[i])))) {
cap[i] -= f; cap[i ^ 1] += f;
res += f; if (!(flow -= f)) break;
}
}
if (!flow || !res) dis[u] = 0;
return res;
}
int Run() {
int sum_flow = 0;
while (Bfs()) { Cpy(cur, Head); sum_flow += Dfs(S, inf); }
return sum_flow;
}
}
using namespace Dinic;
struct Edge { int u, v, w; } lt[M];
int main () {
File();
n = read(); m = read(); id = read();
For (i, 1, m) {
int u = read(), v = read(), w = read();
lt[i] = (Edge){u, v, w};
}
S = lt[id].u; T = lt[id].v;
For (i, 1, m) if (id != i) {
int res = max(lt[id].w - lt[i].w + 1, 0);
if (res) Add(lt[i].u, lt[i].v, res);
}
printf ("%d\n", Run());
return 0;
}
BZOJ 2521: [Shoi2010]最小生成树(最小割)的更多相关文章
- BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)
题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...
- BZOJ 2521: [Shoi2010]最小生成树
2521: [Shoi2010]最小生成树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 445 Solved: 262[Submit][Statu ...
- 【BZOJ2521】[Shoi2010]最小生成树 最小割
[BZOJ2521][Shoi2010]最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算 ...
- BZOJ2521:[SHOI2010]最小生成树(最小割)
Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可 ...
- BZOJ2521[Shoi2010]最小生成树——最小割
题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...
- 【BZOJ-2521】最小生成树 最小割
2521: [Shoi2010]最小生成树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 415 Solved: 242[Submit][Statu ...
- BZOJ 2561: 最小生成树(最小割)
U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...
- [BZOJ 2127] happiness 【最小割】
题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建 ...
- BZOJ2561最小生成树——最小割
题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...
随机推荐
- MySQL优化技巧总结
MySQL优化的几个大方向 ① 硬件优化 ② 对MySQL配置参数进行优化(my.cnf)此优化需要进行压力测试来进行参数调整 ③ SQL语句方面的优化 ④ 表方面的优化 硬件优化 cpu,内存, ...
- Django之在Python中调用Django环境
Django之在Python中调用Django环境 新建一个py文件,在其中写下如下代码: import os if __name__ == '__main__': os.environ.setdef ...
- agora入门案例
一,下载agora的WebSDK 二,运行index.html 三,输入appID 1.找到appID 2.页面输入appID,查看效果
- #Leetcode# 989. Add to Array-Form of Integer
https://leetcode.com/problems/add-to-array-form-of-integer/ For a non-negative integer X, the array- ...
- ocrosoft 1015 习题1.22 求一元二次方程a*x^2 + b*x + c = 0的根
http://acm.ocrosoft.com/problem.php?id=1015 题目描述 求一元二次方程a*x2 + b*x + c = 0的根.系数a.b.c为浮点数,其值在运行时由键盘输入 ...
- 虚拟机Ubuntu图形界面进入命令行快捷键
ctrl+alt+f2 https://jingyan.baidu.com/article/03b2f78c69e5c25ea337ae40.html https://www.zabbix.com/d ...
- ssh登录
ssh 用户名@IP地址 -p 端口号 ssh root@127.0.0.1 -p 2222
- mysql中的几种日志了解
前言 MySQL中有以下日志文件,分别是: 1:重做日志(redo log) 2:回滚日志(undo log) 3:二进制日志(binlog) 4:错误日志(errorlog) 5:慢查询日志(slo ...
- npm --save-dev 和--save 参数的区别
npm中的--save与--save-dev参数的区别 --save一般规定把产品运行时(或生产环境)需要的npm包存入到package.json的dependencies中: --save-dev则 ...
- VUE项目问题之:去掉url中的#/
一.问题 使用VUE路由,项目的url总是带有锚点,如下: http://localhost:8082/#/ 二.解决 修改路由文件中 index.js 文件,即 src --> router ...