【洛谷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的讲课) 链剖分,是指一类 ...
随机推荐
- mssql sqlserver 添加表注释和添加列注释的方法分享
转自: http://www.maomao365.com/?p=8919 摘要: 下文讲述使用sql脚本对数据表或数据列添加注释(备注说明)的方法分享,如下所示: 实验环境:sql server 2 ...
- CodeForces - 1251D (贪心+二分)
题意 https://vjudge.net/problem/CodeForces-1251D 您是一个大型企业的负责人.在您的企业当中共有n位员工为您工作,而且非常有趣的事是这个n是一个奇数(n不能被 ...
- 从公司实际沟通中-得知bug的描述与为什么要bug留痕
从公司实际沟通中-得知bug的描述与为什么要bug留痕 最近在做的一个实际项目.下图为我们的聊天记录,仔细看图,领悟: 从中预期可以学习到的: 1)实际公司--Bug描述的另一个方法: 2)实际公司- ...
- 实际场景:UI、原型与实际不符;研发怼你,你要怎么办?-Dotest软件测试
实际公司场景:UI.原型与实际不符:你提交的问题(bug),开发又开始怼你,遇到这种情况,你会怎么办?怎么沟通?(如下图) 解释:大部分公司都是这样,区别在于差异性有多大:做出来的东西大部分与设计.原 ...
- 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛
传送门 A.^&^ 题意: 找到最小的正数\(C\),满足\((A\ xor\ C)\&(B\ xor \ C)\)最小. 思路: 输出\(A\&B\)即可,特判答案为0的情况 ...
- 洛谷 P4017 最大食物链计数
洛谷 P4017 最大食物链计数 洛谷传送门 题目背景 你知道食物链吗?Delia生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条.于是她来就来求助你,然而你也不会啊!写 ...
- IDEA springboot配置
基于springboot2.1.7 springboot项目创建 springboot热部署 springboot配置swagger2 springboot配置mybatis springboot配置 ...
- 从零开始的微信小程序入门教程(一)
之前说要和同事一起开发个微信小程序项目,现在也在界面设计,功能定位等需求上开始实施了.所以在还未正式写项目前,打算在空闲时间学习下小程序.本意是在学习过程中结合实践整理出一个较为入门且不是很厚的教程, ...
- LeetCode 217:存在重复元素 Contains Duplicate
题目: 给定一个整数数组,判断是否存在重复元素. Given an array of integers, find if the array contains any duplicates. 如果任何 ...
- 08-Django模板(2)
一.HTML转义 在视图中,通过调用模板传递下文,模板对上下文的传递字符串进行输出时,会对以下字符自动转义.HTML转义的作用:转义后标记代码不会被直接解释执行,而是被直接呈现,防止客户端通过嵌入js ...