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 ...
随机推荐
- openjudge-NOI 2.5-1789 算24
题目链接:http://noi.openjudge.cn/ch0205/1789/ 题解: 并不是非常简单的搜索,需要考虑一些东西…… 首先有运算符优先级的限制,还有括号,数字的顺序也可以调整,如果只 ...
- php环境搭建 (window环境下 eclipse+Wampserver)
看了好多的环境搭建感觉好复杂呀,自己搞了一下简单的可以用了 php的手册 http://www.php.net/manual/zh/ 一,下载 1,下载eclipse http://www.ecl ...
- 牛客红包OI赛 B 小可爱序列
Description 链接:https://ac.nowcoder.com/acm/contest/224/B 来源:牛客网 "我愿意舍弃一切,以想念你,终此一生." " ...
- chmod g+s 、chmod o+t 、chmod u+s:Linux高级权限管理
关于linux下权限操作chmod的一些说明!比rxw高级内容! 转载自http://blog.chinaunix.net/uid-26642180-id-3378119.html Set uid, ...
- Fedora下Eclipse/MyEclipse崩溃的解决方案
Fedora19下使用myeclipse2013时,打开不到一分钟就异常关闭. 默认在home目录下生成一个log文件,里面显示的错误信息,说是libsoup.so文件导致出错.第一个想法是删除这个文 ...
- Oracle常用sql语句。
最近工作中遇到了一些与oracle相关的问题,稍微整理一些工作中用到的SQL语句 时间相关 --查询距当前时间十分钟内的数据 select sysdate -interval '10' minute ...
- 一步一步学习IdentityServer4 (4) 处理特殊需求之-登录等待页面
用IdentityServer3的时候登录如果采用Post方式大家会发现有中间有一个等待Submit空白页面,界面不友好,现在我想把这个修改自定义的页面Loading 在Identityserver3 ...
- android练习
package com.example.wang.testapp2; import android.app.AlertDialog; import android.content.DialogInte ...
- (使用通过混淆+自己第三方保留成功混淆)AndroidStudio 混淆打包
原文:https://blog.csdn.net/mazhidong/article/details/64820838 AndroidStudio中的项目可以用compile的形式引入github上的 ...
- Hive(七)Hive分析窗口函数
一数据准备 cookie1,2015-04-10,1 cookie1,2015-04-11,5 cookie1,2015-04-12,7 cookie1,2015-04-13,3 cookie1,20 ...