CF2147H Maxflow GCD Coloring 题解

news/2025/9/22 19:38:09/文章来源:https://www.cnblogs.com/Scarab/p/19105907

Description

给定一个无向图 \(G\),它有 \(n\) 个顶点,每条边上有一个正整数容量。我们记 \(\textsf{maxflow}(u,v)\)

为图中从源点 \(u\) 到汇点 \(v\) 的最大流值。

我们称图 \(G\)好图,如果存在一个整数 \(d \geq 2\),使得对于所有不同顶点对 \((u,v)\),共有的 \(n \cdot (n-1)\) 个最大流值 \(\textsf{maxflow}(u,v)\) 都能被 \(d\) 整除。特别地,没有边的图显然是好图。

现在给定一张图,你需要给它的顶点染色,使得 每一种颜色对应的顶点诱导出的子图都是好图

请找出所需颜色数目的最小值,并给出一种这样的染色方案。

\(n\leq 50,m\leq\frac{n(n-1)}{2}\)

Solution

先套路性地把最大流转成最小割。然后把初始图就合法的情况判掉。

如果 \(d\) 很大的话我们是难以去刻画所有最大流都是 \(d\) 的倍数的。

所以考虑 \(d=2\) 的情况。由于去钦定最小割是偶数是不好做的,因为我们不知道哪些边构成了最小割,那么不妨让所有割集的权值都是偶数。

然后有个结论是每个点连出来的边的边权之和是偶数就能保证所有割集权值都是偶数。证明就考虑把偶边删掉,由于一个割集可以看成给每个点赋一个 \(0/1\) 的颜色 \(c_i\),对于一条边 \((u,v)\),其在割集等价于 \(c_x\oplus c_y=1\)。由于每个点度数都是偶数,所以总割边数中每个 \(c_i\) 都会异或偶数次,也就是 \(0\)


现在我们考虑钦定每个导出子图的每个点度数都是偶数,经过打表会发现这个是一定可以在颜色数等于 \(2\) 的时候做到的。

具体构造就考虑递归构造,每次先把偶数边去掉,如果不存在奇度点就直接每个点染同样的颜色。否则随便找到一个奇度点 \(x\),把与其有奇数权值连边的 \(y\) 拿出来,两两加一条权值为 \(1\) 的边。

\(x\) 删掉后递归构造,递归回来后把 \(y\) 之间两两连的边去掉。不妨设递归构造出来后之前找到的 \(y\) 中颜色为 \(0\) 的集合为 \(S_0\),颜色为 \(1\) 的集合是 \(S_1\)

由于 \(|S_0|+|S_1|\) 是奇数,所以一定存在恰好一个集合目前每个点的度数都是奇数,另一个全是偶数,因为我们刚把它们两两之间的边去掉。\(x\) 的颜色染每个点度数都是奇数的集合对应的颜色,染完后把边加上即可。

对于初始图合法的情况需要用最小割树判断。

时间复杂度:\(O(n^5)\)

Code

#include <bits/stdc++.h>// #define int int64_tconst int kMaxN = 55, kMaxM = 2.5e3 + 5;int n, m;
int u[kMaxM], v[kMaxM], w[kMaxM], res[kMaxN][kMaxN];
std::vector<std::pair<int, int>> G[kMaxN];namespace Dinic {
const int kMaxN = 55, kMaxM = 1e4 + 5;struct Edge {int v, w, pre;
} e[kMaxM];int tot = 1, n, s, t, tail[kMaxN], cur[kMaxN], dep[kMaxN];
bool tag[kMaxN];void init(int _n, int _s, int _t) {tot = 1, n = _n, s = _s, t = _t;for (int i = 1; i <= n; ++i) tail[i] = 0;
}
void adde(int u, int v, int w) { e[++tot] = {v, w, tail[u]}, tail[u] = tot; }
void add(int u, int v, int w) { adde(u, v, w), adde(v, u, 0); }bool bfs() {for (int i = 1; i <= n; ++i) cur[i] = tail[i], dep[i] = 1e9;std::queue<int> q;dep[s] = 0, q.emplace(s);for (; !q.empty();) {int u = q.front(); q.pop();if (u == t) return 1;for (int i = tail[u]; i; i = e[i].pre) {int v = e[i].v, w = e[i].w;if (w && dep[v] == 1e9) {dep[v] = dep[u] + 1, q.emplace(v);}}}return 0;
}int dfs(int u, int lim) {if (u == t || !lim) return lim;int flow = 0;for (int &i = cur[u]; i; i = e[i].pre) {int v = e[i].v, w = e[i].w;if (w && dep[v] == dep[u] + 1) {int fl = dfs(v, std::min(lim, w));if (!fl) dep[v] = 1e9;e[i].w -= fl, e[i ^ 1].w += fl;lim -= fl, flow += fl;if (!lim) break;}}return flow;
}int maxflow() {int ans = 0;for (; bfs(); ans += dfs(s, 1e9)) {}return ans;
}int calc(int s, int t) {init(::n, s, t);for (int i = 1; i <= m; ++i) add(u[i], v[i], w[i]), add(v[i], u[i], w[i]);return maxflow();
}void dfs(int u = s) {if (u == s) std::fill_n(tag + 1, n, 0);tag[u] = 1;for (int i = tail[u]; i; i = e[i].pre) {int v = e[i].v;if (e[i].w && !tag[v]) dfs(v);}
}
} // namespace Dinicvoid build(std::vector<int> id) {if (id.size() <= 1) return;int s = id[0], t = id[1], w = Dinic::calc(s, t);G[s].emplace_back(t, w), G[t].emplace_back(s, w);Dinic::dfs();std::vector<int> idl, idr;for (auto i : id) (Dinic::tag[i] ? idl : idr).emplace_back(i);build(idl), build(idr);
}void dfs(int u, int fa, int *res) {if (!fa) res[u] = 1e9;for (auto [v, w] : G[u]) {if (v == fa) continue;res[v] = std::min(res[u], w);dfs(v, u, res);}
}void prework() {for (int i = 1; i <= n; ++i) G[i].clear();std::vector<int> id;for (int i = 1; i <= n; ++i) id.emplace_back(i);build(id);for (int i = 1; i <= n; ++i) dfs(i, 0, res[i]);
}bool solve1() {int d = 0;for (int i = 1; i <= n; ++i)for (int j = i + 1; j <= n; ++j)d = std::__gcd(d, res[i][j]);if (d == 1) return 0;std::cout << "1\n" << n << '\n';for (int i = 1; i <= n; ++i) std::cout << i << " \n"[i == n];return 1;
}void solve2() {static int cnt[kMaxN][kMaxN], deg[kMaxN], col[kMaxN];static bool del[kMaxN];for (int i = 1; i <= n; ++i) {deg[i] = 0;for (int j = 1; j <= n; ++j) cnt[i][j] = 0;}std::function<void(int, int)> add = [&] (int u, int v) {cnt[u][v] ^= 1, cnt[v][u] ^= 1;deg[u] ^= 1, deg[v] ^= 1;};for (int i = 1; i <= m; ++i) {if (w[i] & 1) add(u[i], v[i]);}for (int i = 1; i <= n; ++i) col[i] = -1, del[i] = 0;std::function<void()> dfs = [&]() {int x = 0;for (int i = 1; i <= n; ++i) {if (!del[i] && deg[i]) x = i;}if (!x) {for (int i = 1; i <= n; ++i)if (!del[i])col[i] = 0;return;}std::vector<int> id;for (int i = 1; i <= n; ++i)if (cnt[x][i])id.emplace_back(i);del[x] = 1;for (auto i : id) add(x, i);for (int i = 0; i < id.size(); ++i)for (int j = i + 1; j < id.size(); ++j)add(id[i], id[j]);dfs();del[x] = 0;for (int i = 0; i < id.size(); ++i)for (int j = i + 1; j < id.size(); ++j)add(id[i], id[j]);for (auto i : id) {int deg = 0;for (int j = 1; j <= n; ++j)if (col[j] != -1 && col[i] == col[j])deg ^= cnt[i][j];if (deg) add(x, i), col[x] = col[i];col[x] = col[i] ^ deg ^ 1;}};dfs();std::vector<int> vec[2];for (int i = 1; i <= n; ++i) assert(col[i] != -1), vec[col[i]].emplace_back(i);std::cout << "2\n";std::cout << vec[0].size() << '\n';for (auto x : vec[0]) std::cout << x << ' ';std::cout << '\n';std::cout << vec[1].size() << '\n';for (auto x : vec[1]) std::cout << x << ' ';std::cout << '\n';
}void dickdreamer() {std::cin >> n >> m;for (int i = 1; i <= m; ++i) std::cin >> u[i] >> v[i] >> w[i];prework();if (!solve1()) solve2();
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;std::cin >> T;while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详细介绍:深入理解 JVM 字节码文件:从组成结构到 Arthas 工具实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

免费做网站优化网站建设需要费用

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 人脸检测 4.2 局部区域选择 4.3 特征提取 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .........................................…

借助S参数测量评估电容器阻抗第 2 部分

借助S参数测量评估电容器阻抗第 2 部分2025-09-22 19:37 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !…

诸城建设局网站郑州seo优化

为什么80%的码农都做不了架构师&#xff1f;>>> find / -name httpd.conf find / -name access_log 2>/dev/null find /etc -name *srm* find / -amin -10 # 查找在系统中最后10分钟访问的文件 find / -atime -2 # 查找在系统中最后48小时访问的文件 find / -mm…

网站管理设置湖州网站开发公司

解决办法&#xff1a; What solved was to go to Navigate > Reveal in Project Navigator . After this, the structure appeared again.

代做企业网站备案wordpress可视化模板编辑器

简介 本来宏哥一开始打算用真机做的&#xff0c;所以在前边搭建环境时候就没有下载SDK&#xff0c;但是由于许多小伙伴通过博客发短消息给宏哥留言说是没有真机&#xff0c;所以顺应民意整理一下模拟器&#xff0c;毕竟“得民心者&#xff0c;得天下”。SDK顾名思义&#xff0c…

瑞安做微网站平台公司信用评级

逆矩阵&#xff1a;解开线性代数之谜的魔法钥匙 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一同深入探讨线性代数中的重要主题——逆矩阵…

天津品牌网站建设好处网站 建设 领导小组

计算机文件基本上分为二种&#xff1a;二进制文件和 ASCII&#xff08;也称纯文本文件&#xff09;。图形文件及文字处理程序等计算机程序都属于二进制文件。这些文件含有特殊的格式及计算机代码。ASCII 则是可以用任何文字处理程序阅读的简单文本文件&#xff0c;由一些字符的…

网站设计公司种类付费网站怎么做

目录: Java工具类&#xff1a;日期工具类文件上传工具类 短信工具类验证码工具类邮件工具类代码生成器 (SSM)各种依赖的作用&#xff1a;spring-context 依赖&#xff1a;spring-context-supprt 依赖&#xff1a;spring-tx 依赖:mysql-connector-java 依赖&#xff1a;spring-j…

提供常州网站建设俄罗斯的最新军事新闻

架构 先简单介绍zabbix监控的最主要的两个组件&#xff1a; zabbix server zabbix agent server 用来部署 web console以及相关的数据存储&#xff0c;所以需要配合一些数据库来保存数据&#xff0c;比如mysql,pgsql, 又有前端的页面所以还需要配置 nginx 和getway 所以 serve…

个人网站做联盟营销中山技术支持中山网站建设

代码分析 引入tkinter库&#xff0c;并从中导入messagebox模块。 read_users()函数用于读取存储用户信息的文本文件"users.txt"。它打开文件并逐行读取&#xff0c;将每行的用户名和密码以空格分隔后存储在一个列表中&#xff0c;最后返回该列表。 login(username,…

Uiverse.io 2.0 震撼发布:新增 3000+ 动效组件!适配 React、Vue

Uiverse官网https://uiverse.io/elements本文来自博客园,作者:jialiangzai,转载请注明原文链接:https://www.cnblogs.com/zsnhweb/p/19105896

问题及解决方法

语法基础问题 问题:变量作用域、数据类型转换、运算符优先级混淆。 解决:多写代码验证,比如用System.out.println()输出不同运算结果,对比预期和实际值。 面向对象概念模糊 问题:类与对象的关系、封装 / 继承 / 多…

成都武侯区建设厅官方网站浙江省工程建设监理管理协会网站

0 工具准备 1.EtherCAT主站 2.EtherCAT从站&#xff08;本文使用步进电机驱动器&#xff09; 3.Wireshark1 抓包分析 1.1 报文总览 本文设置从站1的对象字典&#xff0c;设置对象字典主索引为0x2000&#xff0c;子索引为0x00&#xff0c;设置值为1500。主站通过发送SDO写报文…

浙江专业网站建设商城报价潮州网站推广优化

戳下方链接&#xff0c;后台回复“230707PS插件”获取相关插件应用 回复“230708PS插件教程”获取教学链接; 回复“230730camera快捷键”获取快捷键链接。 原文链接&#xff1a;https://mp.weixin.qq.com/s/tVNDBPUtKrUtfGmPKJ0Tdw 目标调整工具 作用WindowsmacOS选取目标调整工…

大学生创业服务网站建设方案创业加盟

关于Primitive。 Primitive和Entity&#xff0c;一般翻译成图元和实体&#xff0c;图元更接近底层&#xff0c;实体是封装后的高级对象&#xff0c;使用更加简便。一般来说&#xff0c;Primitive的使用相对繁琐&#xff0c;相比Entity需要使用者自己初始化更多对象&#xff0c…

做关于车的网站好长沙网站制作平台

目录 一、bxCan简介 二、bxCAN总体描述 2.1概述 2.2CAN框图 三、bxCA的工作模式 3.1初始化模式 3.2正常模式 3.3睡眠模式&#xff08;低功耗&#xff09; 四、测试模式 4.1静默模式 4.2环回模式 五、bxCAN功能描述 5.1 发送处理 ​编辑 5.2接收管理 5.2.1 标识符过…

沈阳网站维护公司昌邑网站制作

项目场景&#xff1a; 做单链表反转题目&#xff0c;报错&#xff1a;member access within null pointer of type ‘struct ListNode’ 题目链接:LINK 问题描述 我明明在初始化指针时候&#xff0c;已经处理了n2->next情况却依然报错 这个报错提示含义是&#xff1a;大概就…

网站内容优化方法莱州哪有做网站的

Transform类继承自Component类&#xff0c;并实现了IEnumberable接口。Transform是GameObject必须拥有得一个组件&#xff0c;用来管理所在GameObject对象的坐标位置、选择角度、和大小缩放。 Transform实现了IEnumberable接口&#xff0c;因此可以在程序中使用foreach()方法快…

龙岩网站建设大概费用系部网站建设需求分析运行需求

适配器模式(AdapterPattern, 结构型模式) 用最通俗的讲法就是: 将多个功能相关或不相关的接口( 你需要的接口 )放到同一个实现类里, 构造一个具有多工功能, 多特点的"异类对象" 定义 是作为多个接口之间的桥梁,结合多个独立的接口(将多个类/功能结合在一起,构建出一…