hdu 4685 二分匹配+强连通分量
题目链接:
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]);
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 二分匹配+强连通分量的更多相关文章
- H - Prince and Princess - HDU 4685(二分匹配+强连通分量)
题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚. 分析:先求出来他们的最大匹配,因为给的数据未必是完备 ...
- Prince and Princess HDU - 4685(匹配 + 强连通)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- poj1904 二分图匹配+强连通分量
http://poj.org/problem?id=1904 Description Once upon a time there lived a king and he had N sons. An ...
- hdu 4685(匹配+强连通分量)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 思路:想了好久,终于想明白了,懒得写了,直接copy大牛的思路了,写的非常好! 做法是先求一次最 ...
- 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 ...
- UESTC 898 方老师和缘分 --二分图匹配+强连通分量
这题原来以为是某种匹配问题,后来好像说是强连通的问题. 做法:建图,每个方老师和它想要的缘分之间连一条有向边,然后,在给出的初始匹配中反向建边,即如果第i个方老师现在找到的是缘分u,则建边u-> ...
- hdu 4685 简单匹配+Tarjan算法
思路:首先看到这题以为能用poj1904的模版直接A掉,WA了几次,然后又TLE了几次.还是想到了正解. 一开始我想的大致方向已经是对的了.先是由王子向每个喜欢的公主建边,再求一次最大匹配,找出匹配后 ...
- P5163 WD与地图 [整体二分,强连通分量,线段树合并]
首先不用说,倒着操作.整体二分来做强连通分量,然后线段树合并,这题就做完了. // powered by c++11 // by Isaunoya #include <bits/stdc++.h ...
- HDU 4635 Strongly connected (强连通分量)
题意 给定一个N个点M条边的简单图,求最多能加几条边,使得这个图仍然不是一个强连通图. 思路 2013多校第四场1004题.和官方题解思路一样,就直接贴了~ 最终添加完边的图,肯定可以分成两个部X和Y ...
随机推荐
- 使用notiy和wait模拟阻塞队列
public class MyQueue { //定义一个存储数据的容器 private LinkedList<Object> list = new LinkedList<Objec ...
- Linux下mysql编译安装
一.下载安装包 因为编译安装mysql需要cmake所以先编译安装cmake,这里都一起下载下来 下载cmake,网址https://cmake.org/download/ 下载mysql,网址htt ...
- sql,插入最大值加1
insert into aa (id,name) values((select case when max(id) is null then 1 else max(id)+1 end from aa) ...
- php5.5新函数array_column
php5.5新增了一个新的数组函数,感觉挺使用的,低版本的实现按照如下实现 if(!function_exists('array_column')){ function array_column($i ...
- java8新特性笔记
1.forEach(),遍历数据结构中的元素,括号内可以带一个闭包的方法 2.双冒号用法:forEach(this::doSchedule),如果运行环境是闭包,java允许使用双冒号的写法来直接调用 ...
- [C#] Extension Method 扩展方法
当我们引用第三方的DLL.或者Visual Studio自己的库的时候,或许会发现这样的一个情况,如果这个类型有一个XX的方法就好了.这时候我们可以用到扩展方法,是我们的代码更加灵活和高效. 这里我举 ...
- ViewPager中GridView问题
GridView 嵌套在ViewPager中问题. 1. GridView属性设置无法显示. 正常显示方式 <GridView android:padding="8dip" ...
- Javascript 插件统一的实现步骤
步骤: // 1. 定义立即调用的函数 +function($){ "use strict"; //使用严格模式ES5支持 //后续步骤 // 2. xx 插件类及原型方法的定义 ...
- JS实现浏览器的title闪烁
经常可以看见的title里面的消息提示,下面是JS的一种实现方法:主要是通过setTimeout方法设置一个定时器,切换消息提示,从而达title到消息提示的闪烁. <html> < ...
- Linux驱动开发之字符设备模板
/***************************** ** 驱动程序模板* 版本:V1* 使用方法(末行模式下):* :%s/xxx/"你的驱动名称"/g********* ...