HDU4685:Prince and Princess(二分图匹配+tarjan)
Prince and Princess
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 2281 Accepted Submission(s): 677
题目链接: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
题意:
给出n个王子,m个公主,然后每个王子都有自己喜欢的公主,公主可以接受所有的王子。。现在要求输出每个王子可以的结婚对象,并且他们结婚过后不影响到最大匹配数量。
题解:
先可以参考下POJ1904的题解
然后这个题和POJ1904的不同就在于,这个题n和m是不等的,一开始的最大匹配也没有给出。
在理解了POJ1904的做法过后,对于这道题就考虑一开始利用二分图匹配自己构造一个最大匹配出来。然后将模型转化为上个题的模型:构造虚拟结点使得n,m相等。
具体的构造方法就是有多少单身王子,就构造多少个虚拟公主;有多少个虚拟公主,就构造多少个虚拟王子,并且将虚拟生物与所有异性进行连边。这样就可以使得所有人中没有单身。那么这个问题就转化为上一个问题了,之后就利用POJ1904的方法来做,注意一下输出即可。
我这里二分图匹配写拐了。。太菜了啊,debug了好久。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
typedef long long ll;
const int N = ;
int t;
int n,m,tot;
int match[N],head[N],link[N][N],check[N];
stack <int> s;
vector <int> ans;
int T,num;
int scc[N],dfn[N],low[N],vis[N];
struct Edge{
int u,v,next;
}e[N*N];
void adde(int u,int v){
e[tot].v=v;e[tot].u=u;e[tot].next=head[u];head[u]=tot++;
}
void Tarjan(int u){
dfn[u]=low[u]=++T;vis[u]=;
s.push(u);
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!vis[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}else if(!scc[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
num++;int now;
do{
now = s.top();s.pop();
scc[now]=num;
}while(!s.empty() && now!=u);
}
}
int dfs(int x,int nown){
for(int i=;i<=nown;i++){
if(!check[i] && link[x][i]){
check[i]=;
if(match[i]==- || dfs(match[i],nown)){
match[i]=x;
return ;
}
}
}
return ;
}
int hungry(int n1,int m1){
memset(match,-,sizeof(match));
int ans=;
for(int i=;i<=n1;i++){
memset(check,,sizeof(check));
ans+=dfs(i,m1);
}
return ans ;
}
void init(){
memset(link,,sizeof(link));
memset(match,-,sizeof(match));
memset(head,-,sizeof(head));
memset(scc,,sizeof(scc));
memset(dfn,,sizeof(dfn));
memset(vis,,sizeof(vis));
num=;T=;tot=;
}
int main(){
cin>>t;
int Case = ;
while(t--){
Case++;
init();
scanf("%d%d",&n,&m);
for(int i=,k;i<=n;i++){
scanf("%d",&k);
for(int j=,l;j<=k;j++){
scanf("%d",&l);
link[i][l]=;
}
}
int cnt=hungry(n,m);
int nown,nowm;
nown=nowm=n+m-cnt;
for(int i=n+;i<=nown;i++){
for(int j=;j<=nown;j++){
link[i][j]=;
}
}
for(int i=;i<=n;i++){
for(int j=m+;j<=nowm;j++){
link[i][j]=;
}
}
hungry(nown,nowm);
for(int i=;i<=nown;i++){
for(int j=;j<=nowm;j++){
if(link[i][j]) adde(i,nown+j);
}
}
for(int i=;i<=nown;i++){
if(match[i]!=-) adde(i+nown,match[i]);
}
printf("Case #%d:\n",Case);
while(!s.empty()) s.pop();
for(int i=;i<=*nown;i++){
if(!vis[i]) Tarjan(i);
}
for(int i=;i<=n;i++){
ans.clear();
for(int j=head[i];j!=-;j=e[j].next){
int v=e[j].v;v-=nown;
if(v>m) continue ;
if(scc[i]==scc[v+nown]) ans.push_back(v);
}
sort(ans.begin(),ans.end());
printf("%d",(int)ans.size());
for(int j=;j<ans.size();j++){
printf(" %d",ans[j]);
}
printf("\n");
}
}
return ;
}
HDU4685:Prince and Princess(二分图匹配+tarjan)的更多相关文章
- HDU 4685 Prince and Princess 二分图匹配+tarjan
Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...
- 强连通+二分匹配(hdu4685 Prince and Princess)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- HDU4685 Prince and Princess 完美搭配+良好的沟通
意甲冠军:今天,有n王子,m公主.现在给他们配对,与王子会嫁给一个男人,他喜欢.公主无法做出选择. 这标题去咬硬,还有一类似的题目poj1904.那个题目也是给王子与公主配对,但那个是王子公主各n个, ...
- HDU4685 Prince and Princess【强连通】
题意: 有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚,公主就比较悲惨, 跟谁结婚都行.然后输出王子可能的结婚对象,必须保证王子与任意这些对象中的一个结婚,都不会影 ...
- 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 ...
- Prince and Princess HDU - 4685(匹配 + 强连通)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- UVA - 10635 Prince and Princess LCS转LIS
题目链接: http://bak.vjudge.net/problem/UVA-10635 Prince and Princess Time Limit: 3000MS 题意 给你两个数组,求他们的最 ...
- poj1904 二分图匹配+强连通分量
http://poj.org/problem?id=1904 Description Once upon a time there lived a king and he had N sons. An ...
- P3731 二分图匹配必经边
题意经过一番转换变成了 让你在一个二分图上删一条边使得二分图的最大独立集大小至少+1 二分图的最大独立集=点数-最小点覆盖(最大匹配) 点数是固定不变的 所以我们要减少最大匹配数 则删掉的哪一条边必须 ...
随机推荐
- 【radio-group、radio】 单选项组件说明
radio-group组件是包裹radio组件的容器 原型: <radio-group bindchange="[EventHandle]"> <radio .. ...
- leetcode-颜色分类
颜色分类 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示 ...
- 数据库Mysql的学习(一)-启动和进入
数据库:按照数据结构来组织储存和管理数据的仓库. Mysql是关系型数据库管理系统 Mysql安装好之后... mysql的启动 1:通过控制面板里的”服务“找到mysql右键启动即可 2:开始菜单搜 ...
- selenium中的三种等待方式(显示等待WebDriverWait()、隐式等待implicitly()、强制等待sleep())---基于python
我们在实际使用selenium或者appium时,等待下个等待定位的元素出现,特别是web端加载的过程,都需要用到等待,而等待方式的设置是保证脚本稳定有效运行的一个非常重要的手段,在selenium中 ...
- JavaScript中childNodes和children的区别
我在学习JavaScript对DOM操作的过程中,发现了使用childNodes属性,得不到我想要的结果,因此我就从JavaScript高级程序设计中了解了childNodes和children的区别 ...
- Thunder团队第五周 - Scrum会议1
Scrum会议1 小组名称:Thunder 项目名称:i阅app Scrum Master:杨梓瑞 工作照片: 邹双黛在照相,所以图片中没有该同学. 参会成员: 王航:http://www.cnblo ...
- 搭建独立域名博客 -- 独立域名博客上线了 www.hanshuliang.com
博客是安装在阿里云的服务器上. 小结 : -- 进入数据库命令 :mysql -uroot -p123456 ; -- 检查nginx配置语法 :.../nginx/sbin/nginx -t; -- ...
- Android中的回调Callback
回调就是外部设置一个方法给一个对象, 这个对象可以执行外部设置的方法, 通常这个方法是定义在接口中的抽象方法, 外部设置的时候直接设置这个接口对象即可. 例如给安卓添加按钮点击事件, 我们创建了OnC ...
- 项目--uml
[团队信息] 团队项目: 小葵日记--主打记录与分享模式的日记app 队名:日不落战队 队员信息及贡献分比例: 短学号 名 本次作业博客链接 此次作业任务 贡献分配 备注 501 安琪 http:// ...
- 将MathType公式转换为LaTex格式
LaTex编辑公式不够直观,常常会因为结构复杂导致数据或者符号出错,使用MathType编辑公式后再直接转换成LaTex代码可以避免这个问题. 一.首先在MathType中编辑公式 二.然后点击参数— ...