「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\). ...
随机推荐
- docker 初识1
学习网址 https://git.oschina.net/yangllsdev/docker-training https://docs.docker.com/engine/installation/ ...
- vue生命周期钩子函数详解
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_35585701/article/ ...
- 其他 - 02. poolmon 安装
1. 概述 遇到 win10 的内存泄露 32G 内存都能给吃光 2. 思路 rammap 对整体内存做一个诊断 主要是内存分配 用途 状态 poolmon 确认内存的用途 比 rammap 更精确 ...
- vue 实现 多个 数字滚动增加动效
参考网上其他同学写的 具体出处忘了,不然一定贴上,有问题请联系. 图一是具体js代码:二是设置定时器:三是dom节点需要写ref numberGrow (ele) { this.summaryData ...
- 公告 & 留言板 & 随想录
欢迎dalao在评论区留言 \(Q \omega Q\) 公告部分: 博客文章的更新一般被放在周末 当然还是可能会咕 自从改了博客的主题之后,文章中的引用好像都会显示出一堆乱码. 由于之前写过的博文不 ...
- spring中@Component注解
1.@controller 控制器(注入服务) 2.@service 业务(注入dao) 3.@repository dao(实现dao访问) 4.@component (把普通pojo实例化到spr ...
- Python函数基础进阶
函数参数的另一种使用方式 def print_info(name,age): print("Name: %s" %name) print("age: %d" % ...
- ios 底部用定位 fixed。在软件盘出来后,页面元素被顶上去一部分,fixed定位的footer也跑到了上面去。解决方法
ios 底部用定位 fixed.在软件盘出来后,页面元素被顶上去一部分,fixed定位的footer也跑到了上面去.解决方法 $("input").focus(function() ...
- Centos610安装Nexus
1.下载Nexus 地址: https://pan.baidu.com/s/1D5AI6zmuRBSMK0k7j41VuQ 提取码: q50j 选择02-nexus 2.新建nexus账号 u ...
- python函数1_参数,返回值和嵌套
函数 将重复的代码,封装到函数,只要使用直接找函数 函数可以增强代码的模块化和提高代码的重复利用率 函数的定义和调用 格式 def 函数名([参数,参数...]): 函数体 定义函数 import r ...