【洛谷P3329】 [ZJOI2011]最小割(最小割树)
题意:
给出一个无向图,之后有\(q,q\leq 30\)组询问,每组询问有一个\(x\),回答有多少点对\((a,b)\)其\(a-b\)最小割不超过\(x\)。
思路:
这个题做法要最小割树...这个东西大概就是对于当前点集任意选择两个点\(s,t\)作为源点和汇点,然后求出当前最小割,之后两个集合连边为最小割权值;然后两个集合递归下去处理。
显然最后集合中只会存在一个元素,那么最后形成的就是一颗树。
最小割树有一个性质:对于树上\(u,v\)两点,其路径上的边权最小值即为两点的最小割。
这个感谢理解一下?
最后处理的时候每次将点按照集合重排序然后递归下去,另外注意一下更新\(ans\)时的枚举范围,这时两个集合中的任意一对点的最小割都不会超过\(d\)。
直观理解最小割树参见:传送门
代码如下:
/*
* Author: heyuhhh
* Created Time: 2019/10/31 21:20:48
*/
#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 155, M = 10005;
#define _S heyuhhh
template <class T>
struct Dinic{
struct Edge{
int v, next;
T flow, w;
Edge(){}
Edge(int v, int next, T flow, T w) : v(v), next(next), flow(flow), w(w) {}
}e[M << 1];
int head[N], tot;
int dep[N];
bool vis[N];
void init() {
memset(head, -1, sizeof(head)); tot = 0;
}
void adde(int u, int v, T w, T rw = 0) {
e[tot] = Edge(v, head[u], w, w);
head[u] = tot++;
e[tot] = Edge(u, head[v], rw, rw);
head[v] = tot++;
}
bool BFS(int _S, int _T) {
memset(dep, 0, sizeof(dep));
queue <int> q; q.push(_S); dep[_S] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if(!dep[v] && e[i].flow > 0) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[_T] != 0;
}
T dfs(int _S, int _T, T a) {
T flow = 0, f;
if(_S == _T || a == 0) return a;
for(int i = head[_S]; ~i; i = e[i].next) {
int v = e[i].v;
if(dep[v] != dep[_S] + 1) continue;
f = dfs(v, _T, min(a, e[i].flow));
if(f) {
e[i].flow -= f;
e[i ^ 1].flow += f;
flow += f;
a -= f;
if(a == 0) break;
}
}
if(!flow) dep[_S] = -1;
return flow;
}
T dinic(int _S, int _T) {
T max_flow = 0;
while(BFS(_S, _T)) max_flow += dfs(_S, _T, INF);
return max_flow;
}
void color(int u) {
vis[u] = true;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(vis[v] == false && e[i].flow) color(v);
}
}
void pre() {
memset(vis, 0, sizeof(vis));
for(int i = 0; i < tot; i++) e[i].flow = e[i].w;
}
};
Dinic <int> solver;
int n, m;
int c[N][N];
int a[N], ans[N][N];
int tmp1[N], tmp2[N];
void solve(int l, int r) {
if(l >= r) return;
solver.pre();
int S = a[l], T = a[r];
int d = solver.dinic(S, T);
solver.color(S);
for(int i = 1; i <= n; i++) if(solver.vis[i]) {
for(int j = 1; j <= n; j++) if(!solver.vis[j]) {
ans[i][j] = ans[j][i] = min(ans[i][j], d);
}
}
int t1 = 0, t2 = 0;
for(int i = l; i <= r; i++) {
if(solver.vis[a[i]]) tmp1[++t1] = a[i];
else tmp2[++t2] = a[i];
}
for(int i = l; i <= l + t1 - 1; i++) a[i] = tmp1[i - l + 1];
for(int i = l + t1; i <= r; i++) a[i] = tmp2[i - t1 - l + 1];
solve(l, l + t1 - 1); solve(l + t1, r);
}
void run(){
cin >> n >> m;
solver.init();
memset(c, 0, sizeof(c));
memset(ans, INF, sizeof(ans));
for(int i = 1; i <= m; i++) {
int u, v, w; cin >> u >> v >> w;
c[u][v] += w;
c[v][u] = c[u][v];
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(c[i][j]) solver.adde(i, j, c[i][j]);
}
}
for(int i = 1; i <= n; i++) a[i] = i;
solve(1, n);
int q; cin >> q;
for(int k = 1; k <= q; k++) {
int x; cin >> x;
int res = 0;
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
if(ans[i][j] <= x) ++res;
cout << res << '\n';
}
cout << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
【洛谷P3329】 [ZJOI2011]最小割(最小割树)的更多相关文章
- 洛谷P3377 【模板】左偏树(可并堆) 题解
作者:zifeiy 标签:左偏树 这篇随笔需要你在之前掌握 堆 和 二叉树 的相关知识点. 堆支持在 \(O(\log n)\) 的时间内进行插入元素.查询最值和删除最值的操作.在这里,如果最值是最小 ...
- 洛谷 P3377 【模板】左偏树(可并堆)
洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ...
- bzoj 2039 & 洛谷 P1791 人员雇佣 —— 二元关系最小割
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2039 https://www.luogu.org/problemnew/show/P1791 ...
- 最小表示法模板(洛谷P1368 工艺)(最小表示法)
洛谷题目传送门 最小表示是指一个字符串通过循环位移变换(第一个移到最后一个)所能得到的字典序最小的字符串. 因为是环状的,所以肯定要先转化为序列,把原串倍长. 设决策点为一个表示法的开头.比较两个决策 ...
- 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)
题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...
- LOJ #2185 / 洛谷 P3329 - [SDOI2015]约数个数和(莫比乌斯函数)
LOJ 题面传送门 / 洛谷题面传送门 题意: 求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij)\),\(d(x)\) 为 \(x\) 的约数个数. \( ...
- 洛谷AT2046 Namori(思维,基环树,树形DP)
洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...
- ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】
题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...
- LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)
为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...
随机推荐
- 如何为 Automatic Undo Management 调整 UNDO Tablespace 的大小 (Doc ID 262066.1)
How To Size UNDO Tablespace For Automatic Undo Management (Doc ID 262066.1) APPLIES TO: Oracle Datab ...
- Docker 镜像介绍和命令
目录 是什么 UnionFS(联合文件系统) Docker镜像加载原理 分层的镜像 为什么 Docker 镜像要采用这种分层结构呢 特点 Docker镜像commit操作补充 案例演示 1.从Hub上 ...
- limit的优化
SELECT * FROM t_fly WHERE fly_id IN (8888,1,24,6666); 查询速度很快,对于一些过万数据的查询,mysql也能轻松的查询出来
- java8-08-创建stream流
为什么用stream 应用函数式编程 配合Lamdba表达式 更快操作集合类 数组 什么是 stream ...
- xampp配置二级域名通过不同端口访问不同网站
首先需要在xampp\apache\conf\extra\httpd-vhost.conf中写入配置的二级域名 <VirtualHost *:8081> // 该网站通过监测8081端口 ...
- Day4- Python基础4 深浅拷贝、三目运算、列表生成式,迭代器&生成器、装饰器
本节内容: 1.深浅拷贝 2.三目运算 3.迭代器和生成器 4.装饰器 1.深浅拷贝 拷贝意味着对数据重新复制一份,深浅拷贝的含义就是:对于修改复制的数据是否会影响到源数据,拷贝操作对于基本数据结构需 ...
- POJ 2386 Lake Counting 题解《挑战程序设计竞赛》
地址 http://poj.org/problem?id=2386 <挑战程序设计竞赛>习题 题目描述Description Due to recent rains, water has ...
- Java成员变量和局部变量区别
成员变量和局部变量区别 变量根据定义位置的不同,我们给变量起了不同的名字.如下图所示: 区别 在类中的位置不同 (重点) 成员变量:类中,方法外 局部变量:方法中或者方法声明上(形式参数) 作用范围 ...
- Codeforces Round #594 (Div. 1) A. Ivan the Fool and the Probability Theory 动态规划
A. Ivan the Fool and the Probability Theory Recently Ivan the Fool decided to become smarter and stu ...
- 模块基础实战之ATM和购物车系统分文件处理
目录 一.项目地址 二.功能需求 一.项目地址 https://github.com/nickchen121/atm 二.功能需求 FUNC_MSG = { '0': '注销', '1': '登录', ...