题意

对于某一条无向图中的指定边 \((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]最小生成树(最小割)的更多相关文章

  1. BZOJ.2521.[SHOI2010]最小生成树(最小割ISAP/Dinic)

    题目链接 一条边不变其它边减少可以看做一条边增加其它边不变. 假设要加的边lab为(A->B,v),那么肯定是要使除这条边外,A->B的每条路径上的最小权值都\(>v\),这样在连通 ...

  2. BZOJ 2521: [Shoi2010]最小生成树

    2521: [Shoi2010]最小生成树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 445  Solved: 262[Submit][Statu ...

  3. 【BZOJ2521】[Shoi2010]最小生成树 最小割

    [BZOJ2521][Shoi2010]最小生成树 Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算 ...

  4. BZOJ2521:[SHOI2010]最小生成树(最小割)

    Description Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可 ...

  5. BZOJ2521[Shoi2010]最小生成树——最小割

    题目描述 Secsa最近对最小生成树问题特别感兴趣.他已经知道如果要去求出一个n个点.m条边的无向图的最小生成树有一个Krustal算法和另一个Prim的算法.另外,他还知道,某一个图可能有多种不同的 ...

  6. 【BZOJ-2521】最小生成树 最小割

    2521: [Shoi2010]最小生成树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 415  Solved: 242[Submit][Statu ...

  7. BZOJ 2561: 最小生成树(最小割)

    U,V能在最小(大)生成树上,当且仅当权值比它小(大)的边无法连通U,V. 两次最小割就OK了. --------------------------------------------------- ...

  8. [BZOJ 2127] happiness 【最小割】

    题目链接:BZOJ - 2127 题目分析 首先,每个人要么学文科,要么学理科,所以可以想到是一个最小割模型. 我们就确定一个人如果和 S 相连就是学文,如果和 T 相连就是学理. 那么我们再来确定建 ...

  9. BZOJ2561最小生成树——最小割

    题目描述 给定一个边带正权的连通无向图G=(V,E),其中N=|V|,M=|E|,N个点从1到N依次编号,给定三个正整数u,v,和L (u≠v),假设现在加入一条边权为L的边(u,v),那么需要删掉最 ...

随机推荐

  1. (Beta)Let's-M2后分析报告

    设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 在M1阶段我们对用户需求进行了调研,同时M1阶段我们的开发目标就是为了解决用户发起.参与.查看.搜 ...

  2. JDK8-新特性-附demo

    import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Base64; impor ...

  3. CentOS7源码升级OpenSSL和OpenSSH

    一.CentOS7升级OpenSSL 1.查看ssl版本及下载相关依赖包 openssl version -a yum install -y gcc openssl-devel pam-devel r ...

  4. pdf转eps后存在大片空白的处理

    之前pdf转eps的方式是用acrobat直接转,发现每次转完后,图片都显示在一张A4纸上,插入到论文中时会出现大片空白:但在pdf中是没有这么多空白的,与裁剪没关系. 后来在 http://tex. ...

  5. 几个jdbc小技巧

    版本:jdk:1.6mysql-connector-5.0.8 1.如何用jdbc判断某个基本表是否存在 一种比较“笨”的方法:    try{         stmt.executeQuery( ...

  6. Python_编写UDP通信编解码类、文件的上传、远程执行命令、黏包

    1.UDP通信编解码类 (1) 类 # ------------------UDP通信解码编码类------------------------ from socket import * class ...

  7. CentOS下配置SS5(SOCKS5)代理服务器

    方案:使用开源的SS5( Socks Server 5 ) 官网:http://ss5.sourceforge.net/ (点击左侧的Software在右侧的Server处进入下载地址) CentOs ...

  8. oracle常用函数案例

    --INSTR函数 SELECT INSTR(' HELLO WORLD','H') FROM DUAL; --LTRIM RTRIM函数 SELECT LTRIM('*HELLO=','*') FR ...

  9. sass变量引入全局

    https://www.jianshu.com/p/ab9ab999344b(copy) 本文以Sass做案例,Less的参考,基本配置大同小异. 假如我们有一个Sass的全局变量common.scs ...

  10. CodeForces 126B Password

    题目链接:http://codeforces.com/problemset/problem/126/B 题目大意: 多组数据每组给定1个字符串S,问是否存在S的一个尽量长的子串,同时是S的前缀和后缀, ...