nowcoder 清楚姐姐的翅膀们 F 一般图的最大匹配

传送门

文章目录

  • 题意
  • 思路:

题意

在这里插入图片描述

思路:

这个题很容易就会掉到二分图匹配的坑里。。
但实际上这个是一个一般图匹配。
考虑将妹子拆点,一个入点一个出点,入点出点都连蝴蝶结。
我们看看最终会有三种匹配情况:
(1)(1)(1)妹子自身匹配,匹配数+1+1+1
(2)(2)(2)一个妹子的出点或入点其中一个和蝴蝶结匹配,匹配数+1+1+1
(3)(3)(3)一个妹子的出点和入点都和蝴蝶结匹配,匹配数+2+2+2
可以发现,最终有贡献的只有(3)(3)(3),所以求一个最大匹配让后减去nnn即可。

// Problem: 清楚姐姐的翅膀们
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/18962/F?&headNav=acm
// Memory Limit: 1048576 MB
// Time Limit: 10000 ms
// 
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<chrono>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;template <typename T>
class graph {public:struct edge {int from;int to;T cost;};vector<edge> edges;vector<vector<int> > g;int n;graph(int _n) : n(_n) { g.resize(n); }virtual int add(int from, int to, T cost) = 0;
};// undirectedgraph
template <typename T>
class undirectedgraph : public graph<T> {public:using graph<T>::edges;using graph<T>::g;using graph<T>::n;undirectedgraph(int _n) : graph<T>(_n) {}int add(int from, int to, T cost = 1) {assert(0 <= from && from < n && 0 <= to && to < n);int id = (int)edges.size();g[from].push_back(id);g[to].push_back(id);edges.push_back({from, to, cost});return id;}
};// blossom / find_max_unweighted_matching
template <typename T>
vector<int> find_max_unweighted_matching(const undirectedgraph<T> &g) {std::mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());vector<int> match(g.n, -1);   // 匹配vector<int> aux(g.n, -1);     // 时间戳记vector<int> label(g.n);       // "o" or "i"vector<int> orig(g.n);        // 花根vector<int> parent(g.n, -1);  // 父节点queue<int> q;int aux_time = -1;auto lca = [&](int v, int u) {aux_time++;while (true) {if (v != -1) {if (aux[v] == aux_time) {  // 找到拜访过的点 也就是LCAreturn v;}aux[v] = aux_time;if (match[v] == -1) {v = -1;} else {v = orig[parent[match[v]]];  // 以匹配点的父节点继续寻找}}swap(v, u);}};  // lcaauto blossom = [&](int v, int u, int a) {while (orig[v] != a) {parent[v] = u;u = match[v];if (label[u] == 1) {  // 初始点设为"o" 找增广路label[u] = 0;q.push(u);}orig[v] = orig[u] = a;  // 缩花v = parent[u];}};  // blossomauto augment = [&](int v) {while (v != -1) {int pv = parent[v];int next_v = match[pv];match[v] = pv;match[pv] = v;v = next_v;}};  // augmentauto bfs = [&](int root) {fill(label.begin(), label.end(), -1);iota(orig.begin(), orig.end(), 0);while (!q.empty()) {q.pop();}q.push(root);// 初始点设为 "o", 这里以"0"代替"o", "1"代替"i"label[root] = 0;while (!q.empty()) {int v = q.front();q.pop();for (int id : g.g[v]) {auto &e = g.edges[id];int u = e.from ^ e.to ^ v;if (label[u] == -1) {  // 找到未拜访点label[u] = 1;        // 标记 "i"parent[u] = v;if (match[u] == -1) {  // 找到未匹配点augment(u);          // 寻找增广路径return true;}// 找到已匹配点 将与她匹配的点丢入queue 延伸交错树label[match[u]] = 0;q.push(match[u]);continue;} else if (label[u] == 0 && orig[v] != orig[u]) {// 找到已拜访点 且标记同为"o" 代表找到"花"int a = lca(orig[v], orig[u]);// 找LCA 然后缩花blossom(u, v, a);blossom(v, u, a);}}}return false;};  // bfsauto greedy = [&]() {vector<int> order(g.n);// 随机打乱 orderiota(order.begin(), order.end(), 0);shuffle(order.begin(), order.end(), rng);// 将可以匹配的点匹配for (int i : order) {if (match[i] == -1) {for (auto id : g.g[i]) {auto &e = g.edges[id];int to = e.from ^ e.to ^ i;if (match[to] == -1) {match[i] = to;match[to] = i;break;}}}}};  // greedy// 一开始先随机匹配greedy();// 对未匹配点找增广路for (int i = 0; i < g.n; i++) {if (match[i] == -1) {bfs(i);}}return match;
}int main() {ios::sync_with_stdio(0), cin.tie(0);int _; cin>>_;while(_--) {int n,m; cin>>n>>m;undirectedgraph<int>g(n*2+m);for(int i=0;i<n;i++) {g.add(i,i+n,1);int c; cin>>c;while(c--) {int x; cin>>x;x--;g.add(i,2*n+x);g.add(i+n,2*n+x);}}auto blossom_match = find_max_unweighted_matching(g);int ans=0;for(int i=0;i<blossom_match.size();i++) {if(blossom_match[i]!=-1) ans++;}cout<<ans/2-n<<endl;}
}

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

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

相关文章

HDU - 7072 Boring data structure problem 双端队列 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 你需要实现如下四个操作 q≤1e7q\le1e7q≤1e7 思路&#xff1a; 做的时候想了个链表的思路让队友写了&#xff0c;懒。 看了题解感觉题解还是很妙的。 你需要快速插入一个数在前后两端&#xff0c;还需要…

C#中谁最快:结构还是类?

前言在内存当道的日子里&#xff0c;无论什么时候都要考虑这些代码是否会影响程序性能呢&#xff1f;在现在的世界里&#xff0c;几乎不会去考虑用了几百毫秒&#xff0c;可是在特别的场景了&#xff0c;往往这几百毫米确影响了整个项目的快慢。通过了解这两者之间的性能差异&a…

阅读nopcommerce startup源码

创建一个asp.net core项目&#xff0c;可以到到startup类有两个方法// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services)public void Configure(IApplicationBuilder a…

HDU - 7073 Integers Have Friends 2.0 随机化 + 质因子

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个序列aaa&#xff0c;找一个最大的集合&#xff0c;集合中所有元素模mmm相等。 思路&#xff1a; 之前做过一道连续的&#xff0c;直接尺取就好&#xff0c;这个不连续加大了难度。 考虑最简单的…

一份关于.NET Core云原生采用情况调查

调查背景Kubernetes 越来越多地在生产环境中使用&#xff0c;围绕 Kubernetes 的整个生态系统在不断演进&#xff0c;新的工具和解决方案也在持续发布。云原生计算的发展驱动着各个企业转向遵循云原生原则&#xff08;启动速度快、内存占用低&#xff09;的平台&#xff0c; .N…

KPI在小型产品团队中的实践

最近公司决定对所有技术人员实行KPI考核&#xff0c;曾经一度非常反感KPI的我也被要求制定产品团队的KPI指标。为什么要实行KPI考核&#xff0c;因为在项目团队和产品团队的管理中出现了问题&#xff1a;不同项目团队的开发人员的工作量饱和度问题&#xff0c;阶段性会出现有的…

历久弥新 - 微软万亿市值背后的文化支撑(上)|DevOps案例研究

内容来源&#xff1a;DevOps案例深度研究-Microsoft文化支撑研究战队&#xff08;本文只展示部分PPT研究成果&#xff0c;更多细节请关注案例分享会&#xff0c;及本公众号。&#xff09;本案例内容贡献者&#xff1a;陈飞&#xff08;Topic Leader&#xff09;、陈雨卿、郭子奇…

ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建

在上一个小系列文章《ASP.NET Core on K8S学习初探》中&#xff0c;通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境&#xff0c;并初步尝试将ASP.NET Core WebAPI项目部署到了K8S&#xff0c;把玩了一下快速部署和实例伸缩。这个系列开始&#xff0c;会继续学…

我眼中的 NCC,WTM 寻亲之旅

峥嵘岁月如谢花流水&#xff0c;三朝五帝如散雾云海。开发语言更迭如此。我们所坚持的&#xff0c;只是那最初的感动&#xff0c;那“只是在人群中多看了你一眼”的惊艳。三十年河东&#xff0c;三十年河西&#xff0c;不忘初心&#xff0c;方得始终&#xff01;嗯&#xff0c;…

Codeforces Round #594 (Div. 2) C. Ivan the Fool and the Probability Theory 思维 + dp

文章目录题意&#xff1a;思路题意&#xff1a; 思路 一开始找规律&#xff0c;表都打好了&#xff0c;没找出来。。 找规律还是适合让队友来。 先考虑第一行&#xff0c;我们先计算第一行的方案数&#xff0c;设f[i][j]f[i][j]f[i][j]表示到了iii位&#xff0c;第iii位的颜色…

Wtm携手LayUI -- .netcore 开源生态我们是认真的!

经过WTM团队和LayUI团队多次深入协商&#xff0c;双方于2019年7月29日在北京中国国际展览中心正式达成战略合作意向&#xff0c;双方签署了战略合作框架协议&#xff0c;LayUI团队承诺使用WTM框架的任何项目都可以免费使用其收费版的后台模板&#xff0c;WTM团队则从受捐助款项…

Codeforces Round #305 (Div. 1) D. Mike and Fish 欧拉回路

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 欧拉回路经典题。 将其转换成图上问题&#xff0c;对于横纵坐标我们将其分开&#xff0c;对于(x,y)(x,y)(x,y)我们将其横纵坐标连一个无向边&#xff0c;现在问题就转换成了我们需要对每条…

高性能动态编译库Natasha发布1.0版本!

一、 前言对于开源贡献者&#xff0c;Emit和表达式树不是陌生的字眼&#xff0c;IL的动态特性为封装工作带来了极大的方便&#xff0c;会Emit的开发者可以说驾驭了大部分的高性能、高动态的编程技巧。纵观ef、dapper、json.net等第三方常用库&#xff0c;哪个能脱离emit而独善其…

Codeforces Round #245 (Div. 1) E. Points and Segments 欧拉回路 + 建模

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 考虑对于线段&#xff0c;如何建模。 我们考虑先将线段转换成左闭右开的形式&#xff0c;将左右点连起来。 再考虑每个点&#xff0c;将所有离散化后的点拿出来&#xff0c;每个点都有一个…

微软.Net Core 3.0 预览版7发布:大幅减少 SDK 空间大小

据悉&#xff0c;这个预览版是 .Net Core 3 中重要的版本&#xff0c;可以视为原计划在 7 月发布的 RC 版本 (引自微软 .NET Core 首席 Program Manager Richard 先生原话&#xff09;&#xff0c;故可在生产环境进行开发和部署。Windows, macOS 和 Linux 版本的Download .NET …

5门可能衰落的编程语言

专注于为北美地区的科技专业人士提供行业见解和分析&#xff0c;以及提供求职消息的技术职业消息服务网站 Dice Insights 近日发表了一篇题为《5 Programming Languages That Are Probably Doomed》的文章。作者主要根据 TIOBE 和 RedMonk 这两个编程语言排行榜&#xff0c;以及…

.NET加水印/验证码的NuGet包

.NET加水印/验证码的NuGet包 我的在前两篇文章中&#xff0c;我介绍了使用Direct2D给图片加水印/验证码&#xff0c;今天我将其进行了封装&#xff0c;发布了一个NuGet包Sdcb.Imaging&#xff1a;<PackageReference Include"Sdcb.Imaging" Version"1.1.0&quo…

hdu1686:KMP板子

题目链接 题目大意就是给你两个字符串&#xff0c;求出第一个字符串在第二个字符串中出现的次数。 如果我们暴力匹配的话&#xff0c;复杂度是 len(first) * len(second) 对于题目给的 1e4 * 1e6 显然暴力不可取&#xff0c; 这里就用到 KMP 。 说到 KMP 最难理解的就是 next…

集群故障处理之处理思路以及健康状态检查(三十三)

前言 按照笔者的教程&#xff0c;大家应该都能够比较顺畅的完成k8s集群的部署&#xff0c;不过由于环境、配置以及对Linux、k8s的不了解会导致很多问题、异常和故障&#xff0c;这里笔者分享一些处理技巧和思路&#xff0c;以及部分常见的问题&#xff0c;以供大…

Trie初步

简单的描述就是一个字典树&#xff0c; 我们用下图来简单描述一下。 上述的字典树代表着 ab abc abk cd ca b 这六个单词&#xff0c;我们不难发现其中标记是红色的代表从一个伪根节点到这是一个完整的单词。不同的单词有重复的部分&#xff0c;例如accepted&#xff0c;accep…