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 ...
随机推荐
- python高性能web框架——Japronto
近期做了一个简单的demo需求,搭建一个http server,支持简单的qa查询.库中有10000个qa对,需要支持每秒10000次以上的查询请求. 需求比较简单,主要难点就是10000+的RPS. ...
- 日期时间设置 "2018-05-04T16:36:23.6341371+08:00" 格式
using System;using System.Collections.Generic;using System.Globalization;using System.Text; namespac ...
- mysql自增id归0
mysql自增id归0 ALTER TABLE table_name AUTO_INCREMENT=1;
- sqlserver游标概念与实例全面解说
引言 我们先不讲游标的什么概念,步骤及语法,先来看一个例子: ?????? 表一 OriginSalary????????????????????????????????????????????? ...
- switch case语句
五.switch case语句 1.格式 Switch(表达式) { case 表达式:语句块 break: … default break: } 2.例题 输入年份.月份.日期,判断是否是闰年,并且 ...
- 为django的python manage.py加自定义命令
计划在开发软件的过程中, 每次可以自己加入测试数据,这样就可以每次作全新的测试了. 将这个初始化django modules数据命令,将在manage.py里是最合适的. 下面我们就来实现吧. 参考文 ...
- 【LOJ】#2070. 「SDOI2016」平凡的骰子
题解 用了一堆迷之复杂的结论结果迷之好写的计算几何???? 好吧,要写立体几何了 如果有名词不懂自己搜吧 首先我们求重心,我们可以求带权重心,也就是x坐标的话是所有分割的小四面体的x坐标 * 四面体体 ...
- js的等值比较规则
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness ES2015中有四种 ...
- babel使用中不想使用 严格模式 如何去除?
使用babel进行es6转es5时,默认转化之后是严格模式,有些时候我们想去除严格模式. 解决方法如下 安装 babel-plugin-transform-remove-strict-mode 依赖 ...
- Java学习笔记之:Spring MVC 环境搭建
一.创建项目 1.新建java动态项目 2.在web-inf/lib文件夹下导入jar 3.创建所需要的包和文件 二.搭建SpringMVC 1.配置web.xml(WEB-INF下) <?xm ...