hdu4685 最大匹配可能性
题意:
给你n个王子和m个公主,每个王子可以和自己喜欢的公主结婚,问你在不影响最大匹配的前提下每个王子都可以去哪些公主.
思路:
所有王子向他喜欢的公主连一条边,然后匹配一遍,之后再每个匹配的公主连一条指向娶她的王子一条边,然后对于那些光棍王子和单身公主们,其实他们可以和任意他们喜欢的人匹配,因为可以让自己幸福,然后拆散一对别人已经匹配好的,虽然不道德,但是仍然满足总的最大匹配数不变,所以对于每一个光棍男我们就给他虚拟出一个女朋友,所有人都喜欢这个女的,但是这个女的只喜欢并且和该光棍男匹配,女的也类似这样弄,最后每个人都有匹配的对象了,此时我们只要跑一遍强连通,同一个强连通分量里的男和女可以随意匹配..
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<map> #define N_node 5000
#define N_edge 600000
using namespace std; typedef struct
{
int to ,next;
}STAR; STAR E[N_edge] ,_E[N_edge] ,__E[N_edge];
map<int ,map<int ,int> >mk_map;
int list[N_node] ,_list[N_node] ,tot , _tot;
int Belong[N_node] ,cout;
int mk_dfs[N_node] ,mk_gx[N_node];
int mk_M[550] ,mk_G[550];
stack<int>st; void add(int a, int b)
{
E[++tot].to = b;
E[tot].next = list[a];
list[a] = tot; _E[++_tot].to = a;
_E[_tot].next = _list[b];
_list[b] = _tot;
} int DFS_XYL(int s)
{
for(int k = list[s] ;k ;k = E[k].next)
{
int to = E[k].to;
if(mk_dfs[to]) continue;
mk_dfs[to] = 1;
if(mk_gx[to] == -1 || DFS_XYL(mk_gx[to]))
{
mk_gx[to] = s;
return 1;
}
}
return 0;
} void DFS_1(int s)
{
mk_dfs[s] = 1;
for(int k = list[s] ;k ;k = E[k].next)
{
int to = E[k].to;
if(mk_dfs[to]) continue;
DFS_1(to);
}
st.push(s);
} void DFS_2(int s)
{
mk_dfs[s] = 1;
Belong[s] = cout;
for(int k = _list[s] ;k ;k = _E[k].next)
{
int to = _E[k].to;
if(mk_dfs[to]) continue;
DFS_2(to);
}
} void solve(int cas)
{
int n ,m ,i ,j;
int a ,b ,c;
scanf("%d %d" ,&n ,&m);
memset(list ,0 ,sizeof(list));
memset(_list ,0 ,sizeof(_list));
tot = _tot = 1;
mk_map.clear();
for(i = 1 ;i <= n ;i ++)
{
scanf("%d" ,&c);
while(c--)
{
scanf("%d" ,&a);
add(i ,a + n);
mk_map[i][a] = 1;
}
}
memset(mk_gx ,255 ,sizeof(mk_gx));
int sum = 0;
for(i = 1 ;i <= n ;i ++)
{
memset(mk_dfs ,0 ,sizeof(mk_dfs));
mk_M[i] = DFS_XYL(i);
sum += mk_M[i];
}
for(i = 1 ;i <= m ;i ++)
{
if(mk_gx[i + n] == -1) mk_G[i] = 0;
else
{
mk_G[i] = 1;
add(i + n ,mk_gx[i + n]);
}
}
int nowid = n + m;
for(i = 1 ;i <= n ;i ++)
{
if(mk_M[i]) continue;
nowid ++;
for(j = 1 ;j <= n ;j ++)
add(j ,nowid);
add(nowid ,i);
}
for(i = 1 ;i <= m ;i ++)
{
if(mk_G[i]) continue;
nowid ++;
for(j = 1 ;j <= m ;j ++)
add(nowid ,j + n);
add(i + n ,nowid);
}
memset(mk_dfs ,0 ,sizeof(mk_dfs));
while(!st.empty()) st.pop();
for(i = 1 ;i <= nowid ;i ++)
{
if(mk_dfs[i]) continue;
DFS_1(i);
} cout = 0;
memset(mk_dfs ,0 ,sizeof(mk_dfs));
while(!st.empty())
{
int to = st.top();
st.pop();
if(mk_dfs[to]) continue;
cout ++;
DFS_2(to);
}
printf("Case #%d:\n" ,cas);
int tmp[550];
for(i = 1 ;i <= n ;i ++)
{
int tt = 0;
for(int k = list[i] ;k ;k = E[k].next)
{
int to = E[k].to;
if(mk_map[i][to - n] && Belong[i] == Belong[to])
tmp[++tt] = to - n;
}
sort(tmp + 1 ,tmp + tt + 1);
printf("%d" ,tt);
for(int k = 1 ;k <= tt ;k ++)
printf(" %d" ,tmp[k]);
printf("\n");
}
} int main ()
{
int cas = 1 ,t;
scanf("%d" ,&t);
while(t--)
{
solve(cas++);
}
return 0;
}
hdu4685 最大匹配可能性的更多相关文章
- POJ1904 强联通(最大匹配可能性)
题意: 有n个王子,n个公主,然后给你每个王子喜欢的公主,最后问你在不影响最大匹配的前提下,每个王子可以匹配那些公主. 思路: 是hdu4685的减弱版,之前研究过hdu468 ...
- UVALive 5033 I'm Telling the Truth 二分图最大匹配(略有修改)
I - I'm Telling the Truth Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu ...
- Python学习实践------正向最大匹配中文分词
正向最大匹配分词: 1.加载词典文件到集合中,取词典文件中最大长度词的length 2.每次先在句子中按最大长度分割,然后判断分割的词是否存在字典中,存在则记录此词,调整起始点. 3.不存在则按最大长 ...
- UOJ79 一般图最大匹配
题目描述 从前一个和谐的班级,所有人都是搞OI的.有 nn 个是男生,有 00 个是女生.男生编号分别为 1,-,n1,-,n. 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人 ...
- hdu 1281 二分图最大匹配
对N个可以放棋子的点(X1,Y1),(x2,Y2)......(Xn,Yn);我们把它竖着排看看~(当然X1可以对多个点~) X1 Y1 X2 Y2 X3 Y3 ..... Xn Yn ...
- POJ 2226二分图最大匹配
匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...
- hdu-1179-二分图最大匹配
Ollivanders: Makers of Fine Wands since 382 BC. Time Limit: 2000/1000 MS (Java/Others) Memory Lim ...
- codevs1022 覆盖[Hungary 二分图最大匹配]
codevs1022 覆盖 有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地.如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积. 输入描述 ...
- POJ1274 The Perfect Stall[二分图最大匹配]
The Perfect Stall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 23911 Accepted: 106 ...
随机推荐
- Vue 解决img标签不显示图片问题
今天在写前端页面的时候,上传图片返回图片地址后,<img> 标签居然显示不出来,经过排查,原因是 <img v-if="hotel.url" :src=" ...
- [UNP] TCP 多进程服务器
UNP Part-2: Chapter 5. TCP Client/Server Example 的读书笔记. 阅读本文前,建议先阅读多线程服务器的实现,熟悉常见的 TCP 网络通信 API 的基本使 ...
- 虚拟机测试cobbler,网络安装加载最后出现 dracut:/#
1.cobbler的几个重要概念: distro:发行版系统容,我理解为镜像来源,提供了kernel 和 initrd 文件以及repo源 profile:kickstart文件,用于定制系统,定制安 ...
- HDOJ-2896(AC自动机+文本串中出现了哪几个模板串)
病毒侵袭 HDOJ-2896 主要使用AC自动机解决,其次在query函数中改变一下,用来记录每个模板串出现的次数,还有insert函数中记录模板串的编号 需要注意最好使用结构体,而且不能一次性使用m ...
- js浅拷贝(地址引用)和深拷贝(克隆)
浅拷贝和深拷贝相对于引用类型而言的. js有两大类型值类型(基本数据类型)和引用类型(object,function,array): 值类型保存在栈上,引用类型保存在堆上. 浅拷贝只是单纯的拷贝对象的 ...
- Linux下制作Windows启动U盘的工具
Linux下制作Windows启动U盘的工具 很多人说Linux下制作Windwos启动盘要用GRUB4DOS建立引导,其实不用,有专门的工具的,就像Windows下有Rufus制作Linux启动U盘 ...
- SEO 在 SPA 站点中的实践
背景 观察基于 create-react-doc 搭建的文档站点, 发现网页代码光秃秃的一片(见下图).这显然是单页应用 (SPA) 站点的通病 -- 不利于文档被搜索引擎搜索 (SEO). 难道 S ...
- 前端坑多:使用js模拟按键输入的踩坑记录
坑 一开始在Google搜索了一番,找到了用jQuery的方案,代码量很少,看起来很美好很不错,结果,根本没用-- 我反复试了这几个版本: var e = $.Event('keyup') e.key ...
- go中sync.Mutex源码解读
互斥锁 前言 什么是sync.Mutex 分析下源码 Lock 位运算 Unlock 总结 参考 互斥锁 前言 本次的代码是基于go version go1.13.15 darwin/amd64 什么 ...
- Java学习之随机数的用法
•前言 随机数的产生在一些代码中很常用,也是我们必须要掌握的. 而 Java 中产生随机数的方法主要有三种: new Random() Math.random() currentTimeMillis( ...