CF1835F Good Graph

news/2024/11/14 15:23:48/文章来源:https://www.cnblogs.com/lalaouyehome/p/18546049

小清新图论题。

题目大概说了个关于 hall 定理的东西,不多赘述了。

先处理 NO,这是好处理的,在跑匈牙利的时候如果失配那就把增广到的点集输出即可。

然后处理 YES,注意到两个紧密的集合合并还是紧密的集合。那么我们考虑对每个左部点 \(u\) 找到最小的包含他的紧密的集合 \(S_u\),这个东西怎么求呢?考虑到紧密集合显然是完美匹配的,那么我们直接跑这张图,对于点 \(u\),考虑任意 \(match_v\) 不为 \(u\) 且与 \(u\) 相邻的右部点 \(v\),显然与这些右部点匹配的点都要加入集合,那么我们考虑将 \(u\) 向所有 \(match_v\) 连一条有向边,那么 \(S_u\) 由一张极大闭合子图组成。考虑先跑一遍传递闭包,过程与 floyd 相似,并不是什么高级的东西。然后缩点,然后同一强连通分量中的点是要一一连边的,显然这是最优方案,对于 DAG 上的其它边 \(x\rightarrow y\),考虑是否存在 \(z\) 使得 \(x\rightarrow z\rightarrow y\),若存在则不需要连边,因为这条边是多余的。否则就连。哦对了,一定要把原来匹配好的边加入答案边集。

传递闭包可以用 bitset 实现,所以理论最优复杂度为 \(\mathcal{O}(n^{2.5}+\frac{n^3}{w})\)。但我因为我懒得写 dinic 了,所以写了复杂度更劣的匈牙利,但是可能跑的更快。

代码:

#include <bits/stdc++.h>
#define rep(i, l, r) for (int i (l); i <= (r); ++ i)
#define rrp(i, l, r) for (int i (r); i >= (l); -- i)
#define pii pair <int, int>
#define eb emplace_back
#define ls p << 1
#define rs ls | 1
using namespace std;
constexpr int N = 1e3 + 5;
typedef unsigned long long ull;
typedef long long ll;
inline int rd () {int x = 0, f = 1;char ch = getchar ();while (! isdigit (ch)) {if (ch == '-') f = -1;ch = getchar ();}while (isdigit (ch)) {x = (x << 1) + (x << 3) + ch - 48;ch = getchar ();}return x * f;
}
vector <int> e[N];
int n, m;
bool vis[N << 1];
int match[N << 1];
bool dfs (int u) {for (auto v : e[u]) {if (vis[v]) continue; vis[v] = 1;if (! match[v] || dfs (match[v])) {match[v] = u;match[u] = v;return 1;}} return 0;
}
int S[N], tot;
vector <int> G[N], vec[N];
bitset <N> A[N], B[N], E[N], f[N];
int stk[N], top;
int col[N], cnt;
int dfn[N], low[N], tim;
void tarjan (int u) {stk[++ top] = u, vis[u] = 1;dfn[u] = low[u] = ++ tim;for (auto v : G[u]) {if (! dfn[v]) {tarjan (v);low[u] = min (low[u], low[v]);} else if (vis[v]) low[u] = min (low[u], dfn[v]);}if (low[u] == dfn[u]) {int k = 0; ++ cnt;while (k ^ u) {k = stk[top --]; vis[k] = 0;col[k] = cnt;}}
}
vector <pii> ans;
int main () {// freopen ("1.in", "r", stdin);// freopen ("1.out", "w", stdout);n = rd (), m = rd ();rep (i, 1, m) {int u = rd (), v = rd ();e[u].eb (v);}rep (i, 1, n) {if (! dfs (i)) {rep (j, n + 1, n * 2) if (vis[j]) {S[++ tot] = match[j];}S[++ tot] = i;puts ("NO");printf ("%d\n", tot);rep (i, 1, tot) printf ("%d ", S[i]);return 0;}memset (vis, 0, sizeof vis);}puts ("YES");rep (u, 1, n) {f[u][u] = 1;for (auto v : e[u]) {if (match[v] && match[v] != u) {G[u].eb (match[v]); f[u][match[v]] = 1;}}ans.eb (pii (u, match[u]));}rep (j, 1, n) {rep (i, 1, n) {if (f[i][j]) f[i] |= f[j];}}rep (i, 1, n) if (! dfn[i]) tarjan (i);rep (i, 1, n) vec[col[i]].eb (i);rep (i, 1, cnt) {if (vec[i].size () == 1) continue;for (int j = 0; j < vec[i].size (); ++ j) {ans.eb (pii (vec[i][j], match[vec[i][(j + 1) % vec[i].size ()]]));}}rep (u, 1, n) for (auto v : G[u]) if (col[u] ^ col[v]) E[col[u]][col[v]] = 1;rep (i, 1, cnt) A[i][i] = B[i][i] = 1;rep (i, 1, n) {rep (j, 1, n) {if (f[i][j]) {A[col[i]][col[j]] = B[col[j]][col[i]] = 1;}}}rep (i, 1, cnt) {rep (j, 1, cnt) {if (! E[i][j]) continue;if ((A[i] & B[j]).count () == 2) {ans.eb (pii (vec[i][0], match[vec[j][0]]));}}}printf ("%ld\n", ans.size ());for (auto p : ans) printf ("%d %d\n", p.first, p.second);
}

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

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

相关文章

时区计算,冬夏令时, 计算历史某一刻的某地区的时区

首先来聊聊冬夏令时 ‌冬令时和夏令时是为了节约能源和充分利用光照资源而设立的时间制度。‌在夏季,许多国家和地区会将时钟拨快一小时,称为夏令时,以便让人们早起早睡,减少照明用电。而在冬季,时钟会拨回标准时间,称为冬令时。‌ 历史背景和实施国家 夏令时的概念最早由…

【跟着阿舜学音乐-笔记】1.09音程与协和度

音程 音程是指两个音之间的距离,即一个音到另一个音经过了多少个音高的音高单位。 其中,所经历的音高单位的数量叫做音数。具有不同音数的音之间的距离叫做度。 音程的下方较低的音称为根音(该说法也用于和弦中,指原位中最低的音),上方较高的音称为冠音。以下给出各音程的…

find me-WP

首先给了四张图片第一张宽高有问题修复一下,之后感觉不对劲少了IDAT,修复一下 49444154就好了 修复好第一张图片之后发现了二维码ZmxhZ3s0X3 在第二张图片发现了压缩包提取出来但解压不了 需要把7Z换成PK解压之后在618发现1RVcmVfc 第四张图片发现cExlX1BsY 第五张Yzcllfc0lN…

某大型商超客户采购数据分析(Spark实战)

写了一些使用sparksql以及spark机器学习来进行数据分析的东西,希望能给大家做一些参考项目需求:对某大型商超客户采购数据集进行数据分析 数据来源:https://www.heywhale.com/mw/dataset/656069b19a74cc18269207c4/content首先使用Spark读入数据集,读入文件前要先将文件转为…

2024鹏城杯-re

Rafflesia 先去花指令 a = H@^jHwpsH)[jH{M/\\tBBK_|-O{W.iJZ7\\)|~zaB^H+Lwv{SS|-j@\\_[Y flag = for i in range(len(a)):flag += chr(ord(a[i])^0x18) print(flag)PXFrPohkP1CrPcU7DlZZSGd5WcO6qRB/D1dfbyZFP3ToncKKd5rXDGCA 接着是tls改了表 HElRNYGmBOMWnbDvUCgcpu1QdPqJ…

IDEA如何创建web项目及tomcat设置等

一、Java EE插件启用 1.在启动IDEA时,点击右下角并进入Plugins设置2.选择Java EE相关插件,点击OK然后重启二、创建Web项目 1.点击File->New Project,点击Java Enterprise,勾选web Application。确保已选择正确的jdk2.输入项目名称和存放路径,点击Finish完成三、设置tomca…

.net core生成二维码

安装Net.Codecrete.QrCodeGenerator dotnet add Net.Codecrete.QrCodeGenerator var qr = QrCode.EncodeText("https://baidu.com", QrCode.Ecc.Medium); var bytes = qr.ToBmpBitmap(0, 5, 0, 16777215);//5表示单个像素大小,可按需调整,0表示背景色白色,1677721…

Nuxt.js 应用中的 schema:beforeWrite 事件钩子详解

title: Nuxt.js 应用中的 schema:beforeWrite 事件钩子详解 date: 2024/11/14 updated: 2024/11/14 author: cmdragon excerpt: schema:beforeWrite 钩子是 Vite 提供的一个功能强大的生命周期钩子,允许开发者在 JSON Schema 被写入之前执行自定义操作。利用这个钩子,您可以…

最新项目管理软件趋势,2024年全面盘点11款工具!

2024年,项目管理软件领域继续朝着更加智能化、协同化和自动化的方向发展,满足不同规模企业的需求。随着企业对灵活性、透明度和效率的要求不断提高,项目管理软件在功能和使用方式上持续创新。以下是2024年项目管理软件的最新趋势,并涵盖了国内外多款主流项目管理工具。 1. …

PMP百科网精选:项目管理软件怎么选?这里有答案!

在选择项目管理软件时,企业和项目经理需要综合考虑多个因素,以确保所选的软件能够有效支持项目的各个阶段并满足团队的具体需求。PMP百科网的精选内容通常会根据项目管理的实际需求来推荐适合的软件。以下是选择项目管理软件时应该考虑的几个关键因素: 1. 项目的规模和复杂性…

设备管理系统功能拆解——设备巡检管理

工厂生产过程中,设备的稳定性和可靠性非常重要,设备巡检管理则是确保设备正常运行的关键环节。如果生产线上某台设备在没有任何预兆的情况下出现故障,可能会导致整条生产线停滞,影响后续的交付与客户满意度。 而设备巡检管理则是通过定期和系统性的检查,确保设备在运行过程…

DisplayPort的TYPE-C信号定义和配置功能描述

DisplayPort的备用模式重新配置TYPE-C连接器上的某些引脚以支持其他协议.例如DisplayPort备用模式的USB-C型连接器引脚分配。 VESA规范中列出了不同的解决方案,这些解决方案通过特定的连接器插脚和电线支持USB Type-C上的DP。 24引脚的USB Type-C连接器可以分为七个功能类型:…