题意:

      给你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 最大匹配可能性的更多相关文章

  1. POJ1904 强联通(最大匹配可能性)

    题意:       有n个王子,n个公主,然后给你每个王子喜欢的公主,最后问你在不影响最大匹配的前提下,每个王子可以匹配那些公主. 思路:       是hdu4685的减弱版,之前研究过hdu468 ...

  2. UVALive 5033 I'm Telling the Truth 二分图最大匹配(略有修改)

    I - I'm Telling the Truth Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu ...

  3. Python学习实践------正向最大匹配中文分词

    正向最大匹配分词: 1.加载词典文件到集合中,取词典文件中最大长度词的length 2.每次先在句子中按最大长度分割,然后判断分割的词是否存在字典中,存在则记录此词,调整起始点. 3.不存在则按最大长 ...

  4. UOJ79 一般图最大匹配

    题目描述 从前一个和谐的班级,所有人都是搞OI的.有 nn 个是男生,有 00 个是女生.男生编号分别为 1,-,n1,-,n. 现在老师想把他们分成若干个两人小组写动态仙人掌,一个人负责搬砖另一个人 ...

  5. hdu 1281 二分图最大匹配

    对N个可以放棋子的点(X1,Y1),(x2,Y2)......(Xn,Yn);我们把它竖着排看看~(当然X1可以对多个点~) X1   Y1 X2   Y2 X3   Y3 ..... Xn   Yn ...

  6. POJ 2226二分图最大匹配

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...

  7. hdu-1179-二分图最大匹配

    Ollivanders: Makers of Fine Wands since 382 BC. Time Limit: 2000/1000 MS (Java/Others)    Memory Lim ...

  8. codevs1022 覆盖[Hungary 二分图最大匹配]

    codevs1022 覆盖 有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地.如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积. 输入描述  ...

  9. POJ1274 The Perfect Stall[二分图最大匹配]

    The Perfect Stall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23911   Accepted: 106 ...

随机推荐

  1. 有钱人买钻石+dfs中使用贪心

    有钱人买钻石 ECNU-3306 题解:这个题目,乍一看以为是dp背包,可是数据量却那么大,只有1,5,10,25四种面额的硬币,每种数量若干,要使得能够刚好兑换成功总金额,在此前提下,还要使得硬币数 ...

  2. POJ-2240(floyd算法简单应用)

    Arbitrage poj-2240 #include<iostream> #include<cstdio> #include<cstring> #include& ...

  3. Nginx常见的错误配置

    Blog:博客园 个人 翻译自Common Nginx misconfigurations that leave your web server open to attack Nginx是当前主流的W ...

  4. 【海思】Hi3516A 运行sample_venc的demo内核奔溃(DDR问题)

    作者:李春港 出处:https://www.cnblogs.com/lcgbk/p/14514297.html 目录 一.前言 二.使用memtester对ddr进行压力测试 三.修改uboot的DD ...

  5. Nodejs学习笔记(1) Nodejs安装+借助express模块简单部署服务器

    1 安装 1.1 下载和安装 1.2 什么是REPL?如何使用? 1.3 npm对单一模块的安装和删除功能 1.4 通过package.json自定义模块(安装模块) 1.5 设置全局目录 2 部署网 ...

  6. Python基础之:Python中的IO

    目录 简介 linux输入输出 格式化输出 f格式化 format格式化 repr和str %格式化方法 读写文件 文件对象的方法 使用json 简介 IO就是输入和输出,任何一个程序如果和外部希望有 ...

  7. 通俗地理解面向服务的架构(SOA)以及微服务之间的关系

    SOA是一种软件的应用架构方法,它基于面向对象,但又不是面向对象,整体上是面向服务的架构.SOA由精确的服务定义.松散的构件服务组成,以及业务流程调用等多个方面形成的一整套架构方法. 这话是不是听起来 ...

  8. 茫茫内存,我该如何用 windbg 找到你 ?

    一:背景 1. 讲故事 前天wx上有个朋友丢给我一个dump,让我帮忙鉴定一下某些敏感信息在内存中是否也是加密的,现在数据安全很重要,不仅数据库中的信息要加密,灌到内存后数据同样也需密文存储,随用随解 ...

  9. Kubernetes网络概念初探

    ------------恢复内容开始------------ Kubernetes网络是Kubernetes中一个核心概念.简而言之,Kubernetes网络模型可以确保集群上所有Kubernetes ...

  10. 201871030102-崔红梅 实验二 个人项目—— D{0-1}KP 项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 实验二作业链接 我的课程学习目标 1.熟练掌握将本地代码保存至GitHub中2.掌握折扣背包问题3.回顾动态规划算法和回溯算法4.对java语 ...