「CQOI2016」不同的最小割
「CQOI2016」不同的最小割
传送门
建出最小割树,把每一个点对的最小割抠出来 \(\text{unique}\) 一下就好了。
参考代码:
#include <algorithm>
#include <cstring>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 850 + 10, __ = 8500 * 2 + 10, INF = 2147483647;
int tot = 1, head[_], Cap[__ << 1], Q[_];
struct Edge { int ver, cap, nxt; } edge[__ << 1];
inline void Add_edge(int u, int v, int d) { edge[++tot] = (Edge) { v, d, head[u] }, head[u] = tot ; }
inline void link(int u, int v, int d) { Add_edge(u, v, d), Cap[tot] = d, Add_edge(v, u, 0), Cap[tot] = 0; }
int n, m, dep[_], cur[_], p[_], t1[_], t2[_];
int num; struct node { int x, y, z; } G[_];
int fa[10][_], mn[10][_], len, ans[_ * _];
inline int bfs(int s, int t) {
int hd = 0, tl = 0;
memset(dep + 1, 0, sizeof (int) * n);
Q[++tl] = s, dep[s] = 1;
while (hd < tl) {
int u = Q[++hd];
for (rg int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].ver;
if (dep[v] == 0 && edge[i].cap > 0)
dep[v] = dep[u] + 1, Q[++tl] = v;
}
}
return dep[t] > 0;
}
inline int dfs(int u, int flow, int t) {
if (u == t) return flow;
for (rg int& i = cur[u]; i; i = edge[i].nxt) {
int v = edge[i].ver;
if (dep[v] == dep[u] + 1 && edge[i].cap > 0) {
int res = dfs(v, min(flow, edge[i].cap), t);
if (res) { edge[i].cap -= res, edge[i ^ 1].cap += res; return res; }
}
}
return 0;
}
inline int Dinic(int s, int t) {
for (rg int i = 2; i <= tot; ++i) edge[i].cap = Cap[i];
int res = 0;
while (bfs(s, t)) {
for (rg int i = 1; i <= n; ++i) cur[i] = head[i];
while (int d = dfs(s, INF, t)) res += d;
}
return res;
}
inline void solve(int l, int r) {
if (l == r) return ;
int s = p[l], t = p[l + 1];
G[++num] = (node) { s, t, Dinic(s, t) };
int p1 = 0, p2 = 0;
for (rg int i = l; i <= r; ++i) if (dep[p[i]]) t1[++p1] = p[i]; else t2[++p2] = p[i];
for (rg int i = 1; i <= p1; ++i) p[l + i - 1] = t1[i];
for (rg int i = 1; i <= p2; ++i) p[l + p1 + i - 1] = t2[i];
solve(l, l + p1 - 1), solve(l + p1, r);
}
inline void dfs(int u, int f) {
dep[u] = dep[f] + 1;
for (rg int i = head[u]; i; i = edge[i].nxt) {
int v = edge[i].ver; if (v == f) continue ;
fa[0][v] = u, mn[0][v] = edge[i].cap, dfs(v, u);
}
}
inline int calc(int x, int y) {
int res = INF;
if (dep[x] < dep[y]) swap(x, y);
for (rg int i = 8; ~i; --i)
if (dep[fa[i][x]] >= dep[y]) res = min(res, mn[i][x]), x = fa[i][x];
if (x == y) return res;
for (rg int i = 8; ~i; --i)
if (fa[i][x] != fa[i][y]) res = min(res, min(mn[i][x], mn[i][y])), x = fa[i][x], y = fa[i][y];
return min(res, min(mn[0][x], mn[0][y]));
}
int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), read(m);
tot = 1, memset(head, 0, sizeof head);
for (rg int u, v, d; m--; ) read(u), read(v), read(d), link(u, v, d), link(v, u, d);
for (rg int i = 1; i <= n; ++i) p[i] = i;
num = 0, solve(1, n);
tot = 0, memset(head, tot, sizeof head);
for (rg int i = 1; i <= num; ++i) Add_edge(G[i].x, G[i].y, G[i].z), Add_edge(G[i].y, G[i].x, G[i].z);
fa[0][1] = 0, dfs(1, 0);
for (rg int i = 1; i <= 8; ++i)
for (rg int u = 1; u <= n; ++u)
fa[i][u] = fa[i - 1][fa[i - 1][u]], mn[i][u] = min(mn[i - 1][u], mn[i - 1][fa[i - 1][u]]);
for (rg int i = 1; i <= n; ++i) for (rg int j = i + 1; j <= n; ++j) ans[++len] = calc(i, j);
sort(ans + 1, ans + len + 1);
int QwQ = unique(ans + 1, ans + len + 1) - ans - 1;
printf("%d\n", QwQ);
return 0;
}
「CQOI2016」不同的最小割的更多相关文章
- LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree
2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LibreOJ2042 - 「CQOI2016」不同的最小割
Portal Description 给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图.定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在 ...
- loj2042 「CQOI2016」不同的最小割
分治+最小割 看到题解的第一句话是这个就秒懂了,然后乱七八糟的错误.越界.RE-- #include <algorithm> #include <iostream> #incl ...
- 「BZOJ2127」happiness(最小割)
题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...
- Codechef RIN 「Codechef14DEC」Course Selection 最小割离散变量模型
问题描述 提供中文版本好评,一直以为 Rin 是题目名字... pdf submit 题解 参考了 东营市胜利第一中学姜志豪 的<网络流的一些建模方法>(2016年信息学奥林匹克中国国家队 ...
- BZOJ2007/LG2046 「NOI2010」海拔 平面图最小割转对偶图最短路
问题描述 BZOJ2007 LG2046 题解 发现左上角海拔为 \(0\) ,右上角海拔为 \(1\) . 上坡要付出代价,下坡没有收益,所以有坡度的路越少越好. 所以海拔为 \(1\) 的点,和海 ...
- LOJ_6045_「雅礼集训 2017 Day8」价 _最小割
LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...
- loj #2044. 「CQOI2016」手机号码
#2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- LibreOJ2044 - 「CQOI2016」手机号码
Portal Description 给出两个十一位数\(L,R\),求\([L,R]\)内所有满足以下两个条件的数的个数. 出现至少\(3\)个相邻的相同数字: 不能同时出现\(4\)和\(8\). ...
随机推荐
- Gym安装ubuntu16.04
Step1:将gym克隆到计算机上: git clone https://github.com/openai/gym.git 如果你的电脑没有安装git,那么键入 sudo apt install g ...
- python开发基础04-列表、元组、字典操作练习
练习1: # l1 = [11,22,33]# l2 = [22,33,44]# a. 获取内容相同的元素列表# b. 获取 l1 中有, l2 中没有的元素列表# c. 获取 l2 中有, l1 中 ...
- 第一个vi
选择——VI 在前面板选择波形图表 在程序框图中选择while循环,框住波形图 在编程-数值中选择随机数,连接随机数与波形图 在编程-定时子选项卡中选择--等待下一个整数倍,在数值中选择常量选项,数值 ...
- expdp定时备份
1.创建用户所需的永久表空间和临时表空间 create tablespace tbs_hankey_dat datafile '/opt/oracle/oradata/tbs_hankey.dbf' ...
- element中的分页
在template <template> <div class="Terminal" v-loading="loading"> < ...
- c++调用自己编写的静态库(通过eclipse)
转:https://blog.csdn.net/hao5335156/article/details/80282829 参考:https://blog.csdn.net/u012707739/arti ...
- 解决wps for linux缺失windows字体
操作步骤 1.下载缺失字体 链接: https://pan.baidu.com/s/1ZUbtQ96b8RVbH0LrXb_GlQ 密码: nsr4 2.解压字体 unzip wps-font-sy ...
- 其他 - markdown 常用语法
1. 概述 简述 markdown 相关的标记 2. markdown markdown 概述 简单的标记语言 用作快速排版 使用 使用标记对文章样式进行描述 通过专门的引擎读取, 可以展示简单的样式 ...
- P & R 8
Floorplan: 要做好floorplan需要掌握哪些知识跟技能? 通常,遇到floorplan问题,大致的debug步骤跟方法有哪些? 如何衡量floorplan的QA? T:Block lev ...
- Azure IoT Hub 十分钟入门系列 (4)- 实现从设备上传日志文件/图片到 Azure Storage
本文主要分享一个案例: 10分钟内通过Device SDK上传文件到IoTHub B站视频:https://www.bilibili.com/video/av90224073/ 本文主要有如下内容: ...