HDU 4685 Prince and Princess 二分图匹配+tarjan
Prince and Princess
题目连接:
http://acm.hdu.edu.cn/showproblem.php?pid=4685
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
Hint
题意
有n个王子,m个公主
每个王子喜欢ki个公主,现在把每个王子喜欢的公主都给了出来
国王叫大臣制作一张表,输出每个王子和这个公主结婚之后,满足不会影响别人结婚的条件
如果这个王子和这个公主结婚之后,依旧是一个完备匹配的话,就输出
题解:
和poj 1904不一样的是,这道题并没有给出完备匹配,而且男女人数不相等
这一点的话,我们可以先求一个二分图的最大匹配之后,假设匹配数是cnt
那么把左右两边的点都补充为n+m-cnt个点,然后再跑二分图
跑完之后就可以得到完备匹配了,然后就和1904做法一样了。
空间注意开大一点,不然会迷之wa……
不过我的做法不一样,我后面跑tarjan的时候,是让公主之间连边,让这个王子匹配的公主,和他喜欢的公主连边
然后跑的tarjan
代码
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 3e3+6;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m,k,dfn[maxn],low[maxn],_clock=0,sta[maxn],top;
bool in_sta[maxn];
int changed[maxn],scc,num[maxn],vis[maxn],Left[maxn],Rht[maxn],mp[1005][1005];
vector<int> E[maxn],G[maxn];
vector<int>lft[maxn];
vector<int> ans;
void init()
{
memset(Rht,0,sizeof(Rht));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(sta,0,sizeof(sta));
memset(in_sta,0,sizeof(in_sta));
memset(changed,0,sizeof(changed));
memset(num,0,sizeof(num));
memset(vis,0,sizeof(vis));
memset(mp,0,sizeof(mp));
memset(Left,-1,sizeof(Left));
for(int i=0;i<maxn;i++)E[i].clear(),G[i].clear();
for(int i=0;i<maxn;i++)lft[i].clear();
scc=0;top=0;_clock=0;
}
void tarjan(int x)
{
dfn[x]=low[x]=++_clock;
sta[++top]=x;
in_sta[x]=1;
for(int i=0;i<E[x].size();i++)
{
int v = E[x][i];
if(!dfn[v])
tarjan(v),low[x]=min(low[x],low[v]);
else if(in_sta[v])
low[x]=min(low[x],dfn[v]);
}
if(dfn[x]==low[x])
{
int temp;
++scc;
do{
temp = sta[top--];
in_sta[temp]=0;
changed[temp]=scc;
++num[scc];
}while(temp!=x);
}
}
void add(int x,int y)
{
lft[x].push_back(y);
}
int dfs2(int x){
for(int i=0;i<lft[x].size();i++){
int it=lft[x][i];
if(Left[it] == -1){
Left[it] = x;
Rht[x]=it;
return 1;
}
if(vis[it]) continue;
vis[it] = 1;
if(dfs2(Left[it])){
Left[it] = x;
Rht[x]=it;
return 1;
}
}
return 0;
}
void solve(int cas)
{
init();
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
int x=read();
for(int j=0;j<x;j++)
{
int y=read();
add(i,n+y);
G[i].push_back(y);
}
}
int cnt=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
cnt+=dfs2(i);
}
for(int i=0;i<maxn;i++)lft[i].clear();
memset(Left,-1,sizeof(Left));
for(int i=1;i<=n;i++)
{
for(int j=0;j<G[i].size();j++)
{
mp[i][G[i][j]]=1;
add(i,n+m-cnt+G[i][j]);
}
}
for(int i=n+1;i<=n+m-cnt;i++)
{
for(int j=1;j<=n+m-cnt;j++)
{
mp[i][j]=1;
add(i,n+m-cnt+j);
}
}
for(int i=1;i<=n;i++)
{
for(int j=m+1;j<=n+m-cnt;j++)
{
mp[i][j]=1;
add(i,n+m-cnt+j);
}
}
for(int i=1;i<=n+m-cnt;i++)
{
memset(vis,0,sizeof(vis));
dfs2(i);
}
for(int i=1;i<=n+m-cnt;i++)
{
for(int j=1;j<=n+m-cnt;j++)
{
if(Rht[i]-n-m+cnt!=j&&mp[i][j])
E[Rht[i]-n-m+cnt].push_back(j);
}
}
for(int i=1;i<=(n+m-cnt);i++)
if(!dfn[i])tarjan(i);
printf("Case #%d:\n",cas);
for(int i=1;i<=n;i++)
{
ans.clear();
for(int j=1;j<=m;j++)
{
if(mp[i][j]&&changed[Rht[i]-n-m+cnt]==changed[j])
ans.push_back(j);
}
printf("%d",ans.size());
for(int j=0;j<ans.size();j++)
printf(" %d",ans[j]);
printf("\n");
}
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
solve(i);
return 0;
}
HDU 4685 Prince and Princess 二分图匹配+tarjan的更多相关文章
- HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- HDU 4685 Prince and Princess(二分图+强连通分量)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...
- HDU 4685 Prince and Princess(二分匹配+强联通分量)
题意:婚配问题,但是题目并不要求输出最大匹配值,而是让我们输出,一个王子可以与哪些王妃婚配而不影响最大匹配值. 解决办法:先求一次最大匹配,如果有两个已经匹配的王妃,喜欢她们两个的有两个或者以上相同的 ...
- hdu 4685 Prince and Princess(匈牙利算法 连通分量)
看了别人的题解.须要用到匈牙利算法的强连通算法 #include<cstdio> #include<algorithm> #include<vector> #pra ...
- HDU 4685 Prince and Princess
强连通分量,看大神的题解才会写的.... http://www.cnblogs.com/kuangbin/p/3261157.html 数据量有点大,第一次Submit 2995ms过的,时限3000 ...
- HDU4685:Prince and Princess(二分图匹配+tarjan)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- hdu 3829 Cat VS Dog 二分图匹配 最大点独立集
Cat VS Dog Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others) Prob ...
- HDU 2236 无题II(二分图匹配+二分)
HDU 2236 无题II 题目链接 思路:行列仅仅能一个,想到二分图,然后二分区间长度,枚举下限.就能求出哪些边是能用的,然后建图跑二分图,假设最大匹配等于n就是符合的 代码: #include & ...
- TTTTTTTTTTTTTTTT hdu 5727 Necklace 阴阳珠 二分图匹配+暴力全排列
Necklace Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
随机推荐
- 2016 最佳 Linux 发行版排行榜【转】
转自:http://www.linuxstory.org/the-best-linux-distros-of-2016/?utm_source=tuicool&utm_medium=refer ...
- OpenStack 监控解决方案
正如你们看到的那样,到目前为止(OpenStack Kilo),OpenStack自己的监控组件Telemetry并不是完美, 获取的监控数据以及制作出来的图表有时候让人匪夷所思,因其重点并不是监控而 ...
- 使用脚本实现killproc的功能
在shell提示符号下输入type killproc,会发现killproc实在 /sbin/目录下,通过man killproc可以查看这个脚本(姑且这么称为脚本)的用法,现在,把这个脚本的实现过程 ...
- C# Guid 16位 唯一
public static class GuidExtentions { /// <summary> /// 根据GUID获取16位的唯一字符串 /// </summary> ...
- 基于vue配置axios
转载地址:https://juejin.im/post/5a02a898f265da43052e0c85 1.背景 在项目开发中ajax请求是必不可缺少 一部分ajax请求不需要loading或则请求 ...
- C++ : Boost : Rational 有理数类
因为一些不为人知的原因, 我需要一些能减少我程序误差的东西.于是找到了这个类. 然后下载了Boost这个庞大的库. 安装与配置 在官网上找到下载地址, 大概有71MB, 下来来解压到任意位置就好了. ...
- wpf listBox的item,滚动条拖到低部,底部内容不能完全显示的问题
listBox外部包裹一层 <ScrollViewer VerticalScrollBarVisibility="Auto"> 然后修改listBox的style,取消 ...
- 记一次对 Laravel-permission 项目的性能优化
我最近研究分析了在 SWIS上面创建的项目的性能.令人惊讶的是,最耗费性能的方法之一是优秀的 spatie/laravel-permission 包造成的. 经过查阅更多资料和研究,发现一个可能明显 ...
- 开发 Material Design+RxJava+Retrofit+MVP App 参考资料
前言 在开发一个基于 Material Design+RxJava+Retrofit+MVP 框架的 App 过程中学习的资料整理 —— 由G军仔分享 这里记录了我开发 大象 项目时,所学习的 ...
- Metronic 5.0.5 bootstrap后台管理模板
演示地址:http://keenthemes.com/preview/metronic/ 下载 Dashboard Table