题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4685

题解:

这一题是poj 1904的加强版,poj 1904王子和公主的人数是一样多的,并且给出了一个完美匹配,而这一题王子和公主的人数是不同的,而且没有给出任何匹配。因此借鉴1904的做法,我们可以对这题做一些预处理,从而使得它和poj 1904一样能够用强连通分量来求解。

首先求出一个最大匹配,对于每一个没有匹配的王子,加一个虚拟的公主与之匹配,对于每一个没有匹配的公主,加一个虚拟的的王子与之匹配,这样就可以得到一个完美匹配了。并且使得所有的王子都与虚拟的公主连边,所有的公主都与每一个虚拟的王子相连

这样建完图后就可以和poj 1904一样的做法了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std; const int maxn = ; int scan() {
int ret = , flag = ; char ch;
if ((ch = getchar()) == '-') flag = ;
else if (ch >= ''&&ch <= '') ret = ch - '';
while ((ch = getchar()) >= ''&&ch <= '') ret = ret * + ch - '';
return flag ? -ret : ret;
} void out(int x) {
if (x>) out(x / );
putchar(x % + '');
} int _t[maxn], lef[maxn]; int n, m; vector<int> G[maxn],G2[maxn]; //二分图的最大匹配-----------------------------------------------
bool match(int u) {
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if (!_t[v]) {
_t[v] = ;
if (lef[v]==- || match(lef[v])) {
lef[v] = u;
return true;
}
}
}
return false;
} void BM() {
for (int i = ; i < n; i++) {
memset(_t, , sizeof(_t));
match(i);
}
//for (int i = 0; i < m; i++) {
// printf("lef[%d]:%d\n", i + 1, lef[i]+1);
//}
}
//--------------------------------------------------------------- //tarjan求强连通----------------------------------------------
int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;
stack<int> S; void dfs(int u) {
pre[u] = lowlink[u] = ++dfs_clock;
S.push(u);
for (int i = ; i < G2[u].size(); i++) {
int v = G2[u][i];
if (!pre[v]) {
dfs(v);
lowlink[u] = min(lowlink[u], lowlink[v]);
}
else if (!sccno[v]) {
lowlink[u] = min(lowlink[u], pre[v]);
}
}
if (lowlink[u] == pre[u]) {
scc_cnt++;
for (;;) {
int x = S.top(); S.pop();
sccno[x] = scc_cnt;
if (x == u) break;
}
}
} void find_scc(int n) {
dfs_clock = scc_cnt = ;
memset(sccno, , sizeof(sccno));
memset(pre, , sizeof(pre));
for (int i = ; i < n; i++) {
if (!pre[i]) dfs(i);
}
}
//--------------------------------------------------------------- int vis[maxn];
void solve() {
//build
memset(vis, , sizeof(vis));
int tot_n = n;
//构造完美匹配-----------------------
for (int i = ; i < m; i++) {
if (lef[i] == -) {
lef[i] = tot_n++;
}
vis[lef[i]] = ;
}
int tot_m = m;
for (int i = ; i < tot_n; i++) {
if (vis[i] == ) lef[tot_m++] = i;
}
//------------------- //每一个王子心仪的公主的连边
for (int i = ; i < n; i++) {
for (int j = ; j < G[i].size(); j++) {
int v = G[i][j];
G2[i].push_back(v + tot_n);
}
}
//每一个虚拟的王子与所有的公主的连边
for (int i = n; i < tot_n; i++) {
for (int v = ; v < m; v++) {
G2[i].push_back(v + tot_n);
}
}
//所有的王子与每一个虚拟公主连边
for (int i = m; i < tot_n; i++) {
for (int v = ; v < tot_n; v++) {
G2[v].push_back(i+tot_n);
}
}
//每一个公主与和她匹配的那个王子连边
for (int i = ; i < tot_n; i++) {
G2[i + tot_n].push_back(lef[i]);
} //printf("tot_n:%d\n", tot_n);
//for (int i = 0; i < tot_n * 2; i++) {
// printf("%d:", i + 1);
// for (int j = 0; j < G2[i].size(); j++) {
// int v = G2[i][j]; v++;
// printf("%d ", v);
// }
// printf("\n");
//} //solve
find_scc(tot_n*); //for (int i = 0; i < tot_n * 2; i++) {
// printf("sccno[%d]:%d\n", i + 1, sccno[i]);
//} //print
for (int i = ; i < n; i++) {
vector<int> ans;
for (int j = ; j < G[i].size(); j++) {
int v = G[i][j];
if (sccno[i] == sccno[v + tot_n]) ans.push_back(v);
}
sort(ans.begin(), ans.end());
out(ans.size());
for (int i = ; i < ans.size(); i++) {
putchar(' ');
out(ans[i] + );
}
putchar('\n');
}
} void init() {
for (int i = ; i < maxn; i++) G[i].clear(),G2[i].clear();
memset(lef, -, sizeof(lef));
} int main() {
int tc,kase=;
tc = scan();
while (tc--) {
init();
n = scan(); m = scan();
int ct,v;
for (int i = ; i < n; i++) {
ct = scan();
for (int j = ; j < ct; j++) {
v = scan(); v--;
G[i].push_back(v);
}
}
printf("Case #%d:\n", ++kase);
BM();
solve();
}
return ;
}

hdu 4685 二分匹配+强连通分量的更多相关文章

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

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

  2. Prince and Princess HDU - 4685(匹配 + 强连通)

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

  3. poj1904 二分图匹配+强连通分量

    http://poj.org/problem?id=1904 Description Once upon a time there lived a king and he had N sons. An ...

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

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

  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. UESTC 898 方老师和缘分 --二分图匹配+强连通分量

    这题原来以为是某种匹配问题,后来好像说是强连通的问题. 做法:建图,每个方老师和它想要的缘分之间连一条有向边,然后,在给出的初始匹配中反向建边,即如果第i个方老师现在找到的是缘分u,则建边u-> ...

  7. hdu 4685 简单匹配+Tarjan算法

    思路:首先看到这题以为能用poj1904的模版直接A掉,WA了几次,然后又TLE了几次.还是想到了正解. 一开始我想的大致方向已经是对的了.先是由王子向每个喜欢的公主建边,再求一次最大匹配,找出匹配后 ...

  8. P5163 WD与地图 [整体二分,强连通分量,线段树合并]

    首先不用说,倒着操作.整体二分来做强连通分量,然后线段树合并,这题就做完了. // powered by c++11 // by Isaunoya #include <bits/stdc++.h ...

  9. HDU 4635 Strongly connected (强连通分量)

    题意 给定一个N个点M条边的简单图,求最多能加几条边,使得这个图仍然不是一个强连通图. 思路 2013多校第四场1004题.和官方题解思路一样,就直接贴了~ 最终添加完边的图,肯定可以分成两个部X和Y ...

随机推荐

  1. 已经导入了具有相同的简单名称“Interop.DSOFramer, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null”的程序集。

    错误  : 已经导入了具有相同的简单名称“Interop.DSOFramer, Version=1.3.0.0, Culture=neutral, PublicKeyToken=null”的程序集. ...

  2. 打包程序tar

    tar  [选项] tar文件 [目录文件] 常用选项如下所述: -c:创建新的归档文件 -d:检查归档文件与指定目录的差异 -r:向归档文件中追加文件 -v:显示命令的执行日期 -u:只有当需要追加 ...

  3. NetCat使用手册

    简介:   在网络工具中有“瑞士军刀”美誉的NetCat(以下简称nc),在我们用了N年了至今仍是爱不释手.因为它短小精悍(这个用在它身上很适合,现在有人已经将其修改成大约10K左右,而且功能不减少) ...

  4. 使用junit进行Spring测试

    这几天在做SpringMVC的项目,现在总结一下在测试的时候碰到的一些问题. 以前做项目,是在较新的MyEclipse(2013)上面进行Maven开发,pom.xml 文件是直接复制的,做测试的时候 ...

  5. WIN8+VS2013编写发布WCF之三(调用)

    在文二中部署成功后就可以在客户端程序中使用服务了...使用服务的过程总是这么酣畅淋漓.当然,对应文二中的三种部署方式,我也会在此描述三种使用方式,一一对应. 都是新建个程序了,然后开始介绍. 一.VS ...

  6. 【设计模式】策略模式 (Strategy Pattern)

    策略模式是一种很简单的基础模式,用于封装一系列算法,使客户端的访问独立于算法的实现.我们可以”井中取水”来形象的描述策略模式.“取水”是一个动作,完成这个动作的方式有很多中,可以直接用手提.可以用水车 ...

  7. 浅谈Objective-C编译器指令

    ------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS ...

  8. 转 在SQL Server中创建用户角色及授权(使用SQL语句)

     目录 要想成功访问 SQL Server 数据库中的数据 我们需要两个方面的授权 完整的代码示例 使用存储过程来完成用户创建 实例 要想成功访问 SQL Server 数据库中的数据, 我们需要两个 ...

  9. AIDL与service

    Service:Local service,一个进程中的多线程服务. AIDL:remote service,不同进程间通信. Service启动方法: startService():调用方destr ...

  10. Python-memcached的基本使用

    想学Python,又想研究下memcached的客户端,于是拿Python-memcached研究研究~~~ 1.memcached的安装 请参考本博另一文章<Linux下安装memcached ...