传送门

文章目录

  • 题意
  • 思路:

题意

思路:

这个题很容易就会掉到二分图匹配的坑里。。
但实际上这个是一个一般图匹配。
考虑将妹子拆点,一个入点一个出点,入点出点都连蝴蝶结。
我们看看最终会有三种匹配情况:
(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;}
}

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

  1. 牛客2021年七夕节比赛 F 清楚姐姐的翅膀们【带花树】

    传送门 清 楚 姐 姐 的 后 宫 有 很 多 妹 子 , 她 们 都 是 清 楚 姐 姐 的 翅 膀 . 当时觉得是匹配,就狂交了六十多发随机 题意: N N N个妹子, M M M个蝴蝶结 每个蝴 ...

  2. python给乘风破浪的姐姐制作词云打call图

    上一篇python爬取乘风破浪的姐姐弹幕–芒果TV爬虫,将乘风破浪的姐姐前四集的弹幕全部爬下来之后,可以为小姐姐们做一个词云打call图 import json import pandas as pd ...

  3. 小姐姐太强了,动图展示 10 大 Git 命令,不会都难

    code小生 一个专注大前端领域的技术平台 公众号回复Android加入安卓技术群 选自dev.to           作者:Lydia Hallie 机器之心编译        参与:Panda. ...

  4. F. DS图—图非0面积

    仅为记录自己学习 切勿抄袭(一起0分?) 题目描述 编程计算由"1"围成的下列图形的面积.面积计算方法是统计"1"所围成的闭合曲线中"0"点 ...

  5. 【Pytorch神经网络理论篇】 24 神经网络中散度的应用:F散度+f-GAN的实现+互信息神经估计+GAN模型训练技巧

    1 散度在无监督学习中的应用 在神经网络的损失计算中,最大化和最小化两个数据分布间散度的方法,已经成为无监督模型中有效的训练方法之一. 在无监督模型训练中,不但可以使用K散度JS散度,而且可以使用其他 ...

  6. 宅男福利!我用Python做了一个B站跳舞的小姐姐,满屏的美腿!

    点上方蓝色"菜鸟学Python",选"星标"公众号 重磅干货,第一时间送到 周末在家,天气好冷好冷啊,我们这边都下雪了!宅在家里没有啥事情,于是炖了只老母鸡,补 ...

  7. 为什么小姐姐能摇一晚上不倒?

    引言 西安大唐不夜城"不倒翁"女孩街头表演的视频曾一夜走红网络.在大唐不夜城步行街,"不倒翁"小姐姐身姿轻盈眼神妩媚令人梦回大唐,一颦一笑将中国唐朝美人的妩媚娇 ...

  8. python使用字典格式化字符串-Python字符串格式化-学这些就够用了

    一.思考❓❔ 1.什么是字符串格式化? 将变量(对象)的值填充到字符串中 在字符串中解析Python表达式 对字符串进行格式化显示 左对齐.右对齐.居中对齐 保留数字有效位数 2.你学过的字符串格式化 ...

  9. python3在线-荐python3在线编程输入输出总结

    A+B 类型一:多组输入,组数未知 输入:输入包括两个正整数a,b(1 <= a, b <= 10^9),输入数据包括多组. 输出:输出a+b的结果 解读:一行是一组输入,有多行输入,输出 ...

最新文章

  1. Google MapReduce有啥巧妙优化?
  2. 并查集(图论) LA 3644 X-Plosives
  3. asp.core api 通过socket和服务器通信发送udp_【网络通信】TCP的通信过程
  4. 从职场新人到企业高管,她是怎么做到的?
  5. 每天CookBook之Python-037
  6. 微信小程序html modal,微信小程序 modal组件详细介绍
  7. 运维项目经验示例(参考)
  8. java setvalue函数,Java JavaTuples setValue()用法及代码示例
  9. Electron点击右上角关闭按钮隐藏任务栏图标(electron类似杀毒软件的任务栏图标)
  10. 怎么选聚氨酯减震弹簧万向轮
  11. java中公钥,私钥,pkcs1格式,pkcs8格式互转
  12. 寒假的牛客训练赛1补题
  13. 数据恢复软件(列表)
  14. 电力系统暂态分析复习
  15. 2021年2G网络全部退网、3G延期退网!中国联通已正式表态
  16. Java学习笔记10(零压力理解继承多态权限修饰符)
  17. java 8进制串转中文_老杜带你学Java【第六课】
  18. 远程控制软件-向日葵
  19. 南京小米java面经(一面)
  20. 超生男孩被村干部送人 7年后父母花15万元赎回

热门文章

  1. 字符用_连接的是什么加密_防水连接器外壳与铜针表面涂层有什么用?
  2. 你最擅长哪种数学思维?
  3. 过了双十一之后的你。。| 今日最佳
  4. 连锁反应装置积木好玩到尖叫!
  5. 住宅按套内面积算,医院人脸识别黄牛,DNA碱基对可能会扩充,菜鸟发布供应链系统,猪瘟不影响食品安全,这就是今天的大新闻...
  6. 小米3g刷高格固件_小米路由器3G刷了老毛子之后恢复官方固件
  7. 在java中写出html代码,在java里写html代码
  8. python找出一个数的所有因子_python – 找到最大素因子的正确算法
  9. javascript内存泄漏调试工具mac_node.js 内存泄漏的秘密
  10. 汉诺塔问题详细解析zufeoj