Prince and Princess

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

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
 
 
n 个王子, m个公主,王子只能娶他喜欢的,公主可以嫁给任何王子,
对每一个王子求出他能娶的公主的最大集合,使之他娶这个集合内的任何一个,都不影响其他王子的选择
 
首先想到的肯定是匹配,但显然不是多重匹配,
 把每个具有相同公主集合的王子放在一起发现
从任何一个王子出发都能到达所有的公主 那么如果我们从公主向她匹配的王子连一条边
是不是就从任何一个王子出发都能到达其它所有的点
因为是有向图  是不是就是 任何两点之前都至少存在一条可以相互到达的路径
那就是SCC了
 
正确做法是
每个王子向他喜欢的公主连边,进行一次匹配求出最大匹配cnt
然后剩下王子n - cnt个,建立(n - cnt)个虚拟的公主,所有的实体王子都向这些公主连边
剩下公主m - cntge, 建立(m - cnt)个虚拟的王子,这些王子都向所有的实体公主连边
再求一次匹配
最后每个公主向她嫁的王子连边 求强连通就好了

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <bitset>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define rb(a) scanf("%lf", &a)
#define rf(a) scanf("%f", &a)
#define pd(a) printf("%d\n", a)
#define plld(a) printf("%lld\n", a)
#define pc(a) printf("%c\n", a)
#define ps(a) printf("%s\n", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = , INF = 0x7fffffff, maxm = ;
int n, m, s, t;
int head[maxn], cur[maxn], vis[maxn], d[maxn], cnt, nex[maxm << ], nex2[maxm << ];
int head2[maxn], cnt2;
int vis1[maxn], vis2[maxn]; struct node
{
int u, v, c, flag;
}Node[maxm << ], Edge[maxm << ]; void add_(int u, int v, int c, int flag)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].c = c;
Node[cnt].flag = flag;
nex[cnt] = head[u];
head[u] = cnt++;
} void add(int u, int v, int c)
{
add_(u, v, c, );
add_(v, u, , );
} void add2(int u, int v)
{
Edge[cnt2].u = u;
Edge[cnt2].v = v;
nex2[cnt2] = head2[u];
head2[u] = cnt2++;
} bool bfs()
{
queue<int> Q;
mem(d, );
Q.push(s);
d[s] = ;
while(!Q.empty())
{
int u = Q.front(); Q.pop();
for(int i = head[u]; i != -; i = nex[i])
{
int v = Node[i].v;
if(!d[v] && Node[i].c > )
{
d[v] = d[u] + ;
Q.push(v);
if(v == t) return ;
}
}
}
return d[t] != ;
} int dfs(int u, int cap)
{
int ret = ;
if(u == t || cap == )
return cap;
for(int &i = cur[u]; i != -; i = nex[i])
{
int v = Node[i].v;
if(d[v] == d[u] + && Node[i].c > )
{
int V = dfs(v, min(cap, Node[i].c));
Node[i].c -= V;
Node[i ^ ].c += V;
ret += V;
cap -= V;
if(cap == ) break;
}
}
if(cap > ) d[u] = -;
return ret;
} int Dinic()
{
int ans = ;
while(bfs())
{
memcpy(cur, head, sizeof head);
ans += dfs(s, INF);
}
return ans;
} int pre[maxn], low[maxn], sccno[maxn], dfs_clock, scc_cnt;
stack<int> S; void dfs(int u)
{
pre[u] = low[u] = ++dfs_clock;
S.push(u);
for(int i = head2[u]; i != -; i = nex2[i])
{
int v = Edge[i].v;
if(!pre[v])
{
dfs(v);
low[u] = min(low[u], low[v]);
}
else if(!sccno[v])
low[u] = min(low[u], pre[v]);
}
if(low[u] == pre[u])
{
scc_cnt++;
for(;;)
{
int x = S.top(); S.pop();
sccno[x] = scc_cnt;
if(x == u) break;
}
}
}
int G[maxn], ans;
int main()
{
int T;
int kase = ;
rd(T);
while(T--)
{
mem(head, -), mem(head2, -);
mem(vis1, ), mem(vis2, );
cnt = cnt2 = ;
rd(n), rd(m);
s = , t = maxn - ;
bool flag = ;
int tmp, u, v;
int x = max(n, m);
for(int i = ; i <= n; i++)
{
add(s, i, );
rd(tmp);
for(int j = ; j <= tmp; j++)
{
rd(v);
add(i, x + v, );
add2(i, x + v);
}
}
for(int i = ; i <= m; i++) add(x + i, t, );
int max_cnt = Dinic(); int mx = x * ;
for(int i = ; i <= m - max_cnt; i++)
{
mx++;
add(s, mx, );
for(int j = ; j <= m; j++)
add(mx, x + j, ), add2(mx, x + j);
}
for(int i = ; i <= n - max_cnt; i++)
{
mx++;
add(mx, t, );
for(int j = ; j <= n; j++)
add(j, mx, ), add2(j, mx);
}
Dinic();
for(int i = ; i < cnt; i++)
{
if(!Node[i].flag || Node[i].u == s || Node[i].v == t || Node[i].c != ) continue;
add2(Node[i].v, Node[i].u);
}
dfs_clock = scc_cnt = ;
mem(sccno, );
mem(pre, );
for(int i = ; i <= mx; i++)
if(!pre[i]) dfs(i);
printf("Case #%d:\n", ++kase);
for(int i = ; i <= n; i++)
{
ans = ;
for(int j = head2[i]; j != -; j = nex2[j])
{
int v = Edge[j].v;
if(sccno[i] == sccno[v] && v - x <= m)
G[ans++] = v;
}
sort(G, G + ans);
printf("%d", ans);
for(int j = ; j < ans; j++)
{
printf(" ");
printf("%d", G[j] - x);
} printf("\n"); } } return ;
}

Prince and Princess HDU - 4685(匹配 + 强连通)的更多相关文章

  1. H - Prince and Princess - HDU 4685(二分匹配+强连通分量)

    题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚. 分析:先求出来他们的最大匹配,因为给的数据未必是完备 ...

  2. hdu 4685(匹配+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 思路:想了好久,终于想明白了,懒得写了,直接copy大牛的思路了,写的非常好! 做法是先求一次最 ...

  3. HDU4685:Prince and Princess(二分图匹配+tarjan)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  4. HDU 4685 Prince and Princess(二分匹配+强联通分量)

    题意:婚配问题,但是题目并不要求输出最大匹配值,而是让我们输出,一个王子可以与哪些王妃婚配而不影响最大匹配值. 解决办法:先求一次最大匹配,如果有两个已经匹配的王妃,喜欢她们两个的有两个或者以上相同的 ...

  5. 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 ...

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

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

  7. 强连通+二分匹配(hdu4685 Prince and Princess)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  8. POJ 1904 HDU 4685

    这两道题差不多,POJ这道我很久以前就做过,但是比赛的时候居然没想起来.. POJ 这道题的题意是,N个王子每个人都有喜欢的公主,当他们选定一个公主结婚时,必须是的剩下的人也能找到他喜欢的公主结婚. ...

  9. UVA - 10635 Prince and Princess LCS转LIS

    题目链接: http://bak.vjudge.net/problem/UVA-10635 Prince and Princess Time Limit: 3000MS 题意 给你两个数组,求他们的最 ...

随机推荐

  1. 一句话总结K均值算法

    一句话总结K均值算法 核心:把样本分配到离它最近的类中心所属的类,类中心由属于这个类的所有样本确定. k均值算法是一种无监督的聚类算法.算法将每个样本分配到离它最近的那个类中心所代表的类,而类中心的确 ...

  2. join的简单总结

    BAT面试题:现在有T1.T2.T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行? 这个线程问题通常会在第一轮或电话面试阶段被问到,目的是检测你对”join”方法是否熟悉.这个多 ...

  3. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  4. 图像分析函数:skimage.measure中的label、regionprops

    算法解释详细,有算法执行过程动态GIF图的:https://blog.csdn.net/icvpr/article/details/10259577 算法文字解释的简介易懂的:https://www. ...

  5. LeetCode算法题-Find Mode in Binary Search Tree(Java实现)

    这是悦乐书的第246次更新,第259篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第113题(顺位题号是501).给定具有重复项的二叉搜索树(BST),找到给定BST中的 ...

  6. MySql 学习之路-高级1

    Mysql自学之路-高级1 目录: 1.CREATE DATABASE 创建数据库 2.CREATE TABLE 创建数据表 3.INSERT INTO SELECT 把一个表中的数据拷贝到另一个表中 ...

  7. 被低估的.net(上) - 微软MonkeyFest 2018广州分享会活动回顾

    前天, 2018年11月10日, 广州图书馆\微软云开发者社区\广东职业教育信息化研究会\珠三角技术沙龙在广州图书馆负一层1号报告厅搞了一场”微软最有价值专家(MVP)广州分享会 - MonkeyFe ...

  8. 基于tcp的云盘上传下载的模拟

    老师的博客: server端 import json import struct import json import struct import socket import os sk = sock ...

  9. Storm入门(三)HelloWorld示例

    一.配置开发环境 storm有两种操作模式: 本地模式和远程模式.使用本地模式的时候,你可以在你的本地机器上开发测试你的topology, 一切都在你的本地机器上模拟出来; 用远程模式的时候你提交的t ...

  10. 倒计时js

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...