传送门

最小割树

算法

初始时把所有点放在一个集合

从中任选两个点出来跑原图中的最小割

然后按照 \(s\) 集合与 \(t\) 集合的归属把当前集合划分成两个集合,递归处理

这样一共跑了 \(n − 1\) 次最小割

可以证明图中任意一对点之间的最小割的数值都包含在这 \(n − 1\) 个数值当中

把每次求出的最小割看成是两个点之间的边,可以建出一棵树

定理1

任意三点之间的最小割一定是两个相等的较小值和一个较大值

证明

设任意三点 \(a, b, c\) 之间的最小割分别为 \(mincut(a, b), mincut(a, c), mincut(b, c)\)

设 \(mincut(a, b)\) 是这三者中的最小值

那么在做 \(a − b\) 割时,\(c\) 一定属于其中的某一个集合,设其与 \(a\) 同属于一个集合

那么就有 \(mincut(b, c) \le mincut(a, b)\)

又因为 \(mincut(a, b) \le mincut(b, c)\),所以两者相等

定理2

图中至多只有 \(n − 1\) 种不同的最小割

证明

编了一个构造的证明

首先根据定理 \(1\) ,可以转化成如下问题:

\(n\) 个点的无向完全图,要给每一条边染色,要求每个三元环上有两条边同色,求最多可以染多少种颜色

考虑归纳法

假设现在已经有一条长度大于 \(1\) 的链 \(a\) 到 \(b\) 上的边的颜色互不相同

考虑染 \((a,b)\) 这条边

如果链长 \(=2\),那么 \((a,b)\) 只能选择链上某条边的颜色

如果链长 \(>2\),假设两个端点在链上的不是 \((a,b)\) 的边的颜色都是链上某条边的颜色

那么取出其中两条 \((a,c)\) 和 \((c,b)\),\((a,b)\) 只能选择两个中其中一条边的颜色,即链上某条边的颜色

所以可以得到,颜色互不相同的边不能形成环,所以最优的显然是树,即 \(n-1\) 中颜色

Sol

至此问题已经完美解决

建出最小割树,任意两个点的最小割就是路径边权最小值

直接暴力也可以

复杂度貌似 \(\Theta(n^3m)\) \(???\)

# include <bits/stdc++.h>
using namespace std;
typedef long long ll; const int maxn(505);
const int inf(1e9); int first[maxn], n, m, cnt, lev[maxn], vis[maxn], s, t, id[maxn], tmp[maxn], cur[maxn], mincut[maxn][maxn], record[maxn << 4];
queue <int> q; struct Edge {
int to, next, w;
} edge[maxn << 4]; inline void Add(int u, int v, int w) {
edge[cnt] = (Edge){v, first[u], w}, first[u] = cnt++;
edge[cnt] = (Edge){u, first[v], w}, first[v] = cnt++;
record[cnt - 1] = record[cnt - 2] = w;
} inline int Bfs() {
memset(lev, 0, sizeof(lev)), lev[s] = 1, q.push(s);
register int u, e, v;
while (!q.empty()) {
for (u = q.front(), q.pop(), e = first[u]; ~e; e = edge[e].next)
if (edge[e].w && !lev[v = edge[e].to]) lev[v] = lev[u] + 1, q.push(v);
}
return lev[t];
} int Dfs(int u, int maxf) {
if (u == t) return maxf;
register int ret = 0, &e = cur[u], f, v;
for (; ~e; e = edge[e].next)
if (edge[e].w && lev[v = edge[e].to] == lev[u] + 1){
f = Dfs(v, min(edge[e].w, maxf - ret));
ret += f, edge[e].w -= f, edge[e ^ 1].w += f;
if (ret == maxf) return ret;
}
if (!ret) lev[u] = 0;
return ret;
} inline int Dinic() {
register int ret = 0, i;
for (i = 0; i < cnt; ++i) edge[i].w = record[i];
while (Bfs()) memcpy(cur, first, sizeof(cur)), ret += Dfs(s, inf);
return ret;
} void Mark(int u) {
if (vis[u]) return;
register int e;
for (vis[u] = 1, e = first[u]; ~e; e = edge[e].next) if (edge[e].w) Mark(edge[e].to);
} inline void Solve(int l, int r) {
if (l >= r) return;
memset(vis, 0, sizeof(vis)), s = id[l], t = id[r];
register int i, j, mid, d = Dinic();
for (Mark(s), j = 0, i = l; i <= r; ++i) if (vis[id[i]]) tmp[++j] = id[i];
for (mid = l + j - 1, i = l; i <= r; ++i) if (!vis[id[i]]) tmp[++j] = id[i];
for (i = l; i <= r; ++i) id[i] = tmp[i - l + 1];
for (i = 1; i <= n; ++i)
if (vis[i])
for (j = 1; j <= n; ++j)
if (i != j && !vis[j]) mincut[i][j] = mincut[j][i] = min(mincut[i][j], d);
Solve(l, mid), Solve(mid + 1, r);
} int main() {
register int i, j, u, v, w, test;
scanf("%d", &test);
while (test--) {
memset(first, -1, sizeof(first)), cnt = 0;
scanf("%d%d", &n, &m);
for (i = 1; i <= m; ++i) scanf("%d%d%d", &u, &v, &w), Add(u, v, w);
for (i = 1; i <= n; ++i) id[i] = i;
memset(mincut, 63, sizeof(mincut)), Solve(1, n), scanf("%d", &w);
while (w--) {
scanf("%d", &u), v = 0;
for (i = 1; i <= n; ++i)
for (j = i + 1; j <= n; ++j) v += mincut[i][j] <= u;
printf("%d\n", v);
}
putchar('\n');
}
return 0;
}

参考文献

  1. 某鸽姓选手的网络流课件

    2. 垃圾博主自己yy

BZOJ2229: [Zjoi2011]最小割(最小割树)的更多相关文章

  1. [bzoj2229][Zjoi2011]最小割_网络流_最小割树

    最小割 bzoj-2229 Zjoi-2011 题目大意:题目链接. 注释:略. 想法: 在这里给出最小割树的定义. 最小割树啊,就是这样一棵树.一个图的最小割树满足这棵树上任意两点之间的最小值就是原 ...

  2. bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)

    2229: [Zjoi2011]最小割 题目:传送门 题解: 一道非常好的题目啊!!! 蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊.... 开始怀疑是不是题目骗人...难道根本不用网络流?? ...

  3. scu - 3254 - Rain and Fgj(最小点权割)

    题意:N个点.M条边(2 <= N <= 1000 , 0 <= M <= 10^5),每一个点有个权值W(0 <= W <= 10^5),现要去除一些点(不能去掉 ...

  4. 算法笔记--最大流和最小割 && 最小费用最大流 && 上下界网络流

    最大流: 给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow). 最小割: 割是网 ...

  5. 3532: [Sdoi2014]Lis 最小字典序最小割

    3532: [Sdoi2014]Lis Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 865  Solved: 311[Submit][Status] ...

  6. HDU 1394 Minimum Inversion Number(最小逆序数 线段树)

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

  7. POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法

    POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...

  8. 【BZOJ2229】[Zjoi2011]最小割 最小割树

    [BZOJ2229][Zjoi2011]最小割 Description 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有 ...

  9. 紫书 例题 11-2 UVa 1395(最大边减最小边最小的生成树)

    思路:枚举所有可能的情况. 枚举最小边, 然后不断加边, 直到联通后, 这个时候有一个生成树.这个时候,在目前这个最小边的情况可以不往后枚举了, 可以直接更新答案后break. 因为题目求最大边减最小 ...

  10. BZOJ2229[Zjoi2011]最小割——最小割树

    题目描述 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分 ...

随机推荐

  1. 算法导论-MIT笔记

    第一部分 Analysis of Algorithms 算法分析是关于计算机程序性能(performance)和资源利用的理论研究 1 What's more important than perfo ...

  2. Dubbo 自定义异常,你是怎么处理的?

    前言 记录Dubbo对于自定义异常的处理方式. 实现目标 服务层异常,直接向上层抛出,web层统一捕获处理 如果是系统自定义异常,则返回{"code":xxx,"msg& ...

  3. C#-输入输出,类型,运算符,语句的练习——★判断年份是否是闰年★

    //输入一个年份,判断是否是闰年 //(能被4整除却不能被100整除的,年份世纪年份能被400整除的是闰年) Console.Write("请输入一个年份:"); int year ...

  4. 数据挖掘 Apriori Algorithm python实现

    该算法主要是处理关联分析的: 大多书上面都会介绍,这里就不赘述了: dataset=[[1,2,5],[2,4],[2,3],[1,2,4],[1,3],[2,3],[1,3],[1,2,3,5],[ ...

  5. java内存的分配策略

    1.概述 本文是<深入理解java虚拟机>(周志明著)3.6节的笔记整理,文章结构也与书上相同,讲述的是几条最普遍的内存分配策略. 2.对象优先在Eden分配 ** 大多数情况下,对象在新 ...

  6. [LibreOJ #2983]【WC2019】数树【计数】【DP】【多项式】

    Description 此题含有三个子问题 问题1: 给出n个点的两棵树,记m为只保留同时在两棵树中的边时连通块的个数,求\(y^m\) 问题2: 给出n个点的一棵树,另外一棵树任意生成,求所有方案总 ...

  7. C# 聊一聊屏保的设置

    初步认识屏保 进入屏保设置 强行开头,大家都知道我们只需要在搜索框打入“屏保”,就能进入屏保的设置选项.然而箭头指向的位置到底是在Windows的哪个地方呢?这就是写这篇博客的原因. 进入一个屏幕保护 ...

  8. [转] Maven 直接下载依赖项 artifact, dependency:get

    [From]http://dnotes.wikidot.com/dependency:get-example To download an artifact into local repository ...

  9. 利用flask-sqlacodegen快速导入ORM表结构

    利用flask-sqlacodegen快速导入ORM表结构 友情提示:如果是使用pymysql请预先pip install 哦~ 这是window下使用virtualenv环境下执行的 Linux用户 ...

  10. 【实战】Axis2后台Getshell

    实战遇到的情况---任意文件读取,读取/conf/axis2.xml内容,读取用户名和密码登录后台 当然弱口令也是屡试不爽的. 操作起来 1.上传cat.aar(链接:https://pan.baid ...