Prince and Princess

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 150    Accepted Submission(s): 46

Problem Description
There are n princes and m princesses. Princess can marry any prince. But prince can only marry the princess they DO love.
For all princes,give all the princesses that they love. So, there is a maximum number of pairs of prince and princess that can marry.
Now for each prince, your task is to output all the princesses he can marry. Of course if a prince wants to marry one of those princesses,the maximum number of marriage pairs of the rest princes and princesses cannot change.
 
Input
The first line of the input contains an integer T(T<=25) which means the number of test cases.
For each test case, the first line contains two integers n and m (1<=n,m<=500), means the number of prince and princess.
Then n lines for each prince contain the list of the princess he loves. Each line starts with a integer ki(0<=ki<=m), and then ki different integers, ranging from 1 to m denoting the princesses.
 
Output
For each test case, first output "Case #x:" in a line, where x indicates the case number between 1 and T.
Then output n lines. For each prince, first print li, the number of different princess he can marry so that the rest princes and princesses can still get the maximum marriage number.
After that print li different integers denoting those princesses,in ascending order.
 
Sample Input
2
4 4
2 1 2
2 1 2
2 2 3
2 3 4
1 2
2 1 2
 
Sample Output
Case #1:
2 1 2
2 1 2
1 3
1 4
Case #2:
2 1 2
 
Source
 
Recommend
zhuyuanchen520
 

主要构图转化的思路很神奇,我看了题解才会的,T_T

首先n,m个点做一次二分匹配,得到匹配数最大为res.   相当于右边有m-res个点没有匹配,左边有n-res个点没有匹配。

所以在左加m-res个点,和右边所有相连。

在右边加n-res个点,个左边所有相连。

然后做n+m-res,n+m-res个点的二分匹配。

匹配数肯定是n+m-res;

主要是得到匹配的情况。

对于左边的点i.  把i相匹配的在右边的点,向其余和i相连的点连一有向边。

然后做强连通缩点。

如果边u-v. v和u匹配的点在一个连通分支,说明可以交换,可以u->v组合,不影响最大匹配数

 /* ***********************************************
Author :kuangbin
Created Time :2013/8/15 23:20:43
File Name :F:\2013ACM练习\2013多校8\1010.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = ;
int uN,vN;
int g[MAXN][MAXN];
int linker[MAXN];
bool used[MAXN];
bool dfs(int u)
{
for(int v = ; v <= vN;v++)
if(g[u][v] && !used[v])
{
used[v] = true;
if(linker[v] == - || dfs(linker[v]))
{
linker[v] = u;
return true;
}
}
return false;
}
int hungary()
{
int res = ;
memset(linker,-,sizeof(linker));
for(int u = ; u <= uN;u++)
{
memset(used,false,sizeof(used));
if(dfs(u))res++;
}
return res;
}
int lx[MAXN];
const int MAXM = ;//边数
struct Edge
{
int to,next;
}edge[MAXM];
int head[MAXN],tot;
int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN];//Belong数组的值是1~scc
int Index,top;
int scc;//强连通分量的个数
bool Instack[MAXN];
int num[MAXN];//各个强连通分量包含点的个数,数组编号1~scc
//num数组不一定需要,结合实际情况 void addedge(int u,int v)
{
edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++;
}
void Tarjan(int u)
{
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for(int i = head[u];i != -;i = edge[i].next)
{
v = edge[i].to;
if( !DFN[v] )
{
Tarjan(v);
if( Low[u] > Low[v] )Low[u] = Low[v];
}
else if(Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
if(Low[u] == DFN[u])
{
scc++;
do
{
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc;
num[scc]++;
}
while( v != u);
}
}
void solve(int N)
{
memset(DFN,,sizeof(DFN));
memset(Instack,false,sizeof(Instack));
memset(num,,sizeof(num));
Index = scc = top = ;
for(int i = ;i <= N;i++)
if(!DFN[i])
Tarjan(i);
}
void init()
{
tot = ;
memset(head,-,sizeof(head));
} int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,m;
int k;
int T;
scanf("%d",&T);
int iCase = ;
while(T--)
{
iCase++;
scanf("%d%d",&n,&m);
memset(g,,sizeof(g));
int v;
for(int i = ;i <= n;i++)
{
scanf("%d",&k);
while(k--)
{
scanf("%d",&v);
g[i][v] = ;
}
}
uN = n;
vN = m;
int res = hungary();
uN = vN = n + m - res;
for(int i = n+;i <= uN;i++)
for(int j = ;j <= vN;j++)
g[i][j] = ;
for(int i = ;i <= uN;i++)
for(int j = m+;j <= vN;j++)
g[i][j] = ;
hungary();
memset(lx,-,sizeof(lx));
for(int i = ;i <= vN;i++)
if(linker[i] != -)
lx[linker[i]] = i;
init();
for(int i = ;i <= uN;i++)
for(int j = ;j <= vN;j++)
if(g[i][j] && j != lx[i])
addedge(lx[i],j);
solve(vN);
printf("Case #%d:\n",iCase);
vector<int>ans;
for(int i = ;i <= n;i++)
{
ans.clear();
for(int j = ; j <= m;j++)
if(g[i][j] && Belong[j] == Belong[lx[i]])
ans.push_back(j);
int sz = ans.size();
printf("%d",sz);
for(int i = ;i < sz;i++)
printf(" %d",ans[i]);
printf("\n");
}
}
return ;
}

HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)的更多相关文章

  1. HDU 4705 Y (2013多校10,1010题,简单树形DP)

    Y Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submiss ...

  2. HDU 4675 GCD of Sequence (2013多校7 1010题 数学题)

    GCD of Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)T ...

  3. HDU 4685 Prince and Princess 二分图匹配+tarjan

    Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...

  4. HDU 4691 Front compression (2013多校9 1006题 后缀数组)

    Front compression Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Othe ...

  5. HDU 4679 Terrorist’s destroy (2013多校8 1004题 树形DP)

    Terrorist’s destroy Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  6. HDU 4671 Backup Plan (2013多校7 1006题 构造)

    Backup Plan Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total ...

  7. HDU 4667 Building Fence(2013多校7 1002题 计算几何,凸包,圆和三角形)

    Building Fence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)To ...

  8. HDU 4685 Prince and Princess(二分图+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

  9. hdu 4685 Prince and Princess(匈牙利算法 连通分量)

    看了别人的题解.须要用到匈牙利算法的强连通算法 #include<cstdio> #include<algorithm> #include<vector> #pra ...

随机推荐

  1. [ python ] 进程的操作

    目录 (见右侧目录栏导航)- 1. 前言- 2. multiprocess模块- 2.1 multiprocess.Process模块    - 2.2 使用Process模块创建进程    - 2. ...

  2. LightOJ 1323 Billiard Balls(找规律(蚂蚁爬木棍))

    题目链接:https://vjudge.net/contest/28079#problem/M 题目大意: 一个边界长为L宽为W的平面同时发射n个台球,运动K秒,台球碰到桌面及两(多)个台球相撞情况如 ...

  3. 20165301 2017-2018-2 《Java程序设计》第七周学习总结

    20165301 2017-2018-2 <Java程序设计>第七周学习总结 教材学习内容总结 第十一章:JDBC与MySQL数据库 MySQL数据库管理系统 启动MySQL数据库服务器 ...

  4. interesting Integers(数学暴力||数论扩展欧几里得)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAwwAAAHwCAIAAACE0n9nAAAgAElEQVR4nOydfUBT1f/Hbw9202m0r8

  5. SimpleCV install and "You need the python image library to save by filehandle"

    2015年5月3日 22:15:43 在win7下安装了python.simplecv,试着运行simplecv官网第一个hello world程序结果报错,提示说%python%/lib/site- ...

  6. JavaWeb知识回顾-使用IDEA开发一个servlet.

    刚刚开始学习使用IDEA进行开发,好多都不会,本来想直接导入一个eclipse项目,但是出现了好多错误,一时不知道怎么修改,所以就从最基本的servlet开始着手,慢慢熟悉这个工具,下面是使用IDEA ...

  7. OPENSSL问题,使用fsockopen()函数提示错误

    环境配置 系统环境 CentOS7.2WDCP v3.2.2 lanmp PHP 多版本 指定使用5.6 OpenSSL 1.0.2h  3 May 2016 php.ini相关设置allow_url ...

  8. PHP 分割字串 Function 的速度比較(substr/sscanf/preg_match)---substr最快!

    固定長度的字串(假設是 06481a63041b578d702f159f520847f8), 要照固定格式做切割, 使用 PHP 要怎麼切會比較快? 註: 要將此字串切成 => 06 / 48 ...

  9. ceph存储池基本管理

    一,设置默认存储池的pg或pgp的值(推荐100左右),在ceph.conf文件里增加: osd pool default pg num = osd pool default pgp num = 二, ...

  10. [笔记] 几个前端bug的解决方案

    jQuery UI下被拖动的元素上飘 症状出现在几乎所有浏览器里.使用 1.10.x 的draggable,在滚动栏下移(即非处于页面顶部)的时候拖动draggable的元素,它会向上跳一段距离.解决 ...