洛谷

题意:

给出一个无向图,之后有\(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]最小割(最小割树)的更多相关文章

  1. 洛谷P3377 【模板】左偏树(可并堆) 题解

    作者:zifeiy 标签:左偏树 这篇随笔需要你在之前掌握 堆 和 二叉树 的相关知识点. 堆支持在 \(O(\log n)\) 的时间内进行插入元素.查询最值和删除最值的操作.在这里,如果最值是最小 ...

  2. 洛谷 P3377 【模板】左偏树(可并堆)

    洛谷 P3377 [模板]左偏树(可并堆) 题目描述 如题,一开始有N个小根堆,每个堆包含且仅包含一个数.接下来需要支持两种操作: 操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或 ...

  3. bzoj 2039 & 洛谷 P1791 人员雇佣 —— 二元关系最小割

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2039 https://www.luogu.org/problemnew/show/P1791 ...

  4. 最小表示法模板(洛谷P1368 工艺)(最小表示法)

    洛谷题目传送门 最小表示是指一个字符串通过循环位移变换(第一个移到最后一个)所能得到的字典序最小的字符串. 因为是环状的,所以肯定要先转化为序列,把原串倍长. 设决策点为一个表示法的开头.比较两个决策 ...

  5. 洛谷 P3187 BZOJ 1185 [HNOI2007]最小矩形覆盖 (旋转卡壳)

    题目链接: 洛谷 P3187 [HNOI2007]最小矩形覆盖 BZOJ 1185: [HNOI2007]最小矩形覆盖 Description 给定一些点的坐标,要求求能够覆盖所有点的最小面积的矩形, ...

  6. LOJ #2185 / 洛谷 P3329 - [SDOI2015]约数个数和(莫比乌斯函数)

    LOJ 题面传送门 / 洛谷题面传送门 题意: 求 \(\sum\limits_{i=1}^n\sum\limits_{j=1}^md(ij)\),\(d(x)\) 为 \(x\) 的约数个数. \( ...

  7. 洛谷AT2046 Namori(思维,基环树,树形DP)

    洛谷题目传送门 神仙思维题还是要写点东西才好. 树 每次操作把相邻且同色的点反色,直接这样思考会发现状态有很强的后效性,没办法考虑转移. 因为树是二分图,所以我们转化模型:在树的奇数层的所有点上都有一 ...

  8. ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】

    题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...

  9. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

随机推荐

  1. WePy框架的使用

    基本示例 import wepy from 'wepy';//引入wepy框架说明 // 通过继承自wepy.page的类创建页面逻辑 export default class Index exten ...

  2. Redis—简介与安装

    Redis 简介 Redis 安装 Redis 配置文件 # Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程.daemonize yes # 当Redis以守护进 ...

  3. Python 对列表嵌套的数据进行排序

    利用sorted(iterable[, key][, reverse]) key:指定一个接收一个参数的函数,这个函数用于从每个元素中提取一个用于比较的关键字,默认值为None(直接比较元素) rev ...

  4. Scrapy的Spider类和CrawlSpider类

    Scrapy shell 用来调试Scrapy 项目代码的 命令行工具,启动的时候预定义了Scrapy的一些对象 设置 shell Scrapy 的shell是基于运行环境中的python 解释器sh ...

  5. CQRS(Command and Query Responsibility Segregation)与EventSources实例

    CQRS The CQRS pattern and event sourcing are not mere simplistic solutions to the problems associate ...

  6. IDEA2019 Win10 Tomcat Server控制台中文乱码的快速解决办法

    原理 Windows10的控制台使用GBK编码,而Tomcat使用UTF-8编码,导致乱码 解决办法 修改$tomcat/conf/logging.properties文件 # 注释这行 java.u ...

  7. python调用C++实例:用C++对numpy执行BFS(广度优先搜索)

    下文的代码可能展示不全,详情请下载文件:用cpp遍历ndarray.rar 问题背景: 现在我有一张二值图test.npy,需要对其闭区域进行孔洞填充,如下图所示: 文件下载链接:用cpp遍历ndar ...

  8. angular6 升级到 angular7+ 最新Ng-zorro

    angular7 出来有一段时间了,然后我们项目一直用的是angular6, 看到一直再用的Ng-Zorro 更新版本了,然后就觉得把目前的项目也升级一下把. 目前我本地cli版本是6.0.8我要把他 ...

  9. 第04组 Beta冲刺(5/5)

    队名:new game 组长博客 作业博客 组员情况 鲍子涵(队长) 过去两天完成了哪些任务 动画优化 接下来的计划 等待答辩 还剩下哪些任务 让游戏本体运行 遇到了哪些困难 时间太少了 有哪些收获和 ...

  10. vscode源码分析【三】程序的启动逻辑,性能问题的追踪

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...