传送门:Problem 4685

https://www.cnblogs.com/violet-acmer/p/9739990.html

参考资料:

  [1]:二分图的最大匹配、完美匹配和匈牙利算法

  [2]:http://www.cnblogs.com/frog112111/p/3387173.html

题意:

  n个王子和m个公主,王子只能和他喜欢的公主结婚,公主可以和所有的王子结婚,输出所有王子可能的结婚对象。

  必须保证王子与任意这些对象中的一个结婚,都不会影响到剩余的王子的配对数,也就是不能让剩余的王子中突然有一个人没婚可结了。

分析:

  这题是poj 1904的加强版,poj 1904的王子和公主数是相等的,这里可以不等,且poj 1904给出了一个初始完美匹配,但是这题就要自己求。

  所以只要求出完美匹配之后,就和poj 1904的做法就完全相同了。

  那么怎么求出完美匹配呢?一开始我用多重匹配的匈牙利算法来做,但是怎么做都不对.......看了题解才恍然大悟=_=

  先说几个坑,这题有点奇怪,就是所有王子都可以争着和同一个公主结婚,只要该王子喜欢该公主,感觉公主有点悲哀呀........

  比如:

       2 2

      1 1

      1 1

  输出的答案是:

        1 1

1 1

  而不是    

        1 1

         0

  这里就是和poj 1904有点不一样的地方,坑了我好久.........

  求完美匹配:

  先对原图用匈牙利算法做一遍二分图匹配,但是还有可能剩余一些人还没匹配,只要虚拟出一些节点来匹配剩余的点就行了。

  假设王子有剩下的,那么每个剩下的王子就连一个虚拟的公主,这个公主被所有的王子都喜欢。

  假设公主有剩下的,那么每个剩下的公主就连一个虚拟的王子,这个王子喜欢所有的公主

  这样就构成完美匹配了,接下来就是和poj 1904一样了。

AC代码:

 #include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
#define pb push_back
#define mem(a,b) memset(a,b,sizeof a)
const int maxn=+++; int n,m;
//===========匈牙利===========
struct Node
{
int matchM[maxn];
int matchW[maxn];
bool check[maxn];
vector<int >edge[maxn];
void Init()
{
mem(matchM,-);
mem(matchW,-);
for(int i=;i < maxn;++i)
edge[i].clear();
}
void addEdge(int u,int v){
edge[u].pb(v);
}
bool Dfs(int u)
{
for(int i=;i < edge[u].size();++i)
{
int to=edge[u][i];
if(!check[to])
{
check[to]=true;
if(matchW[to] == - || Dfs(matchW[to]))
{
matchW[to]=u;
matchM[u]=to;
return true;
}
}
}
return false;
}
void Hungarian()
{
for(int i=;i <= n;++i)
{
mem(check,false);
Dfs(i);
}
}
}_match;
//============================
//============SCC=============
int scc[maxn];
bool vis[maxn];
vector<int >vs;
vector<int >edge[maxn],redge[maxn];
void addEdge(int u,int v)
{
edge[u].pb(v);
redge[v].pb(u);
}
void Dfs(int u)
{
vis[u]=true;
for(int i=;i < edge[u].size();++i)
{
int to=edge[u][i];
if(!vis[to])
Dfs(to);
}
vs.pb(u);
}
void rDfs(int u,int sccId)
{
scc[u]=sccId;
vis[u]=true;
for(int i=;i < redge[u].size();++i)
{
int to=redge[u][i];
if(!vis[to])
rDfs(to,sccId);
}
}
void Scc()
{
mem(vis,false);
vs.clear();
for(int i=;i <= n;++i)
if(!vis[i])
Dfs(i);
mem(vis,false);
int sccId=;
for(int i=vs.size()-;i >= ;--i)
{
int to=vs[i];
if(!vis[to])
rDfs(to,++sccId);
}
}
//============================
void Init()
{
_match.Init();
for(int i=;i < maxn;++i)
edge[i].clear(),redge[i].clear();
}
int main()
{
int T;
scanf("%d",&T);
for(int kase=;kase <= T;++kase)
{
Init();
scanf("%d%d",&n,&m);
for(int i=;i <= n;++i)
{
int k;
scanf("%d",&k);
while(k--)
{
int v;
scanf("%d",&v);
addEdge(i,v+n);
_match.addEdge(i,v+n);
}
}
_match.Hungarian();//匈牙利算法求最大匹配
int all=n+m;
for(int i=;i <= n;++i)
{
if(_match.matchM[i] == -)//为剩余王子匹配虚拟公主
{
all++;
for(int j=;j <= n;++j)//所有王子都喜欢该虚拟公主
addEdge(j,all);
_match.matchM[i]=all;
_match.matchW[all]=i;
}
}
for(int i=n+;i <= n+m;++i)
{
if(_match.matchW[i] == -)//为剩余公主匹配虚拟王子
{
all++;
for(int j=n+;j <= n+m;++j)//该虚拟王子喜欢所有公主
addEdge(all,j);
_match.matchM[all]=i;
_match.matchW[i]=all;
}
}
for(int i=;i <= all;++i)
if(_match.matchM[i] != -)//所有与王子匹配的公主建一条边连向王子
addEdge(_match.matchM[i],i);
Scc();//求强连通分量
printf("Case #%d:\n",kase);
for(int i=;i <= n;++i)
{
int res=;
int ans[maxn];
for(int j=;j < edge[i].size();++j)
{
int to=edge[i][j];
if(scc[i] == scc[to] && to <= m+n)//剔除掉虚拟的公主
ans[res++]=to-n;
}
sort(ans,ans+res);
printf("%d",res);
for(int i=;i < res;++i)
printf(" %d",ans[i]);
printf("\n");
}
}
}

Kosaraju算法

hdu 4685(强连通分量+二分图的完美匹配)的更多相关文章

  1. hdu 4685(强连通分量+二分图)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:n个王子和m个公主,王子只能和他喜欢的公主结婚,公主可以和所有的王子结婚,输出所有王子可能 ...

  2. POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)

    题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...

  3. (step6.3.5)hdu 1281(棋盘游戏——二分图的完美匹配)

    题目大意:本体是中文题.读者可以直接在OJ上看 解题思路: 1)完美匹配:所有的端点都是匹配点 2)对于二分图的完美匹配,我们需要用一个数组来存储匹配点.(而二分图的其他问题(我们则可以直接使用变量来 ...

  4. codevs 1222 信与信封问题(二分图的完美匹配)

    1222 信与信封问题   题目描述 Description John先生晚上写了n封信,并相应地写了n个信封将信装好,准备寄出.但是,第二天John的儿子Small John将这n封信都拿出了信封. ...

  5. UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)

    UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

  6. UVa 11383 少林决胜(二分图最佳完美匹配)

    https://vjudge.net/problem/UVA-11383 题意: 给定一个N×N矩阵,每个格子里都有一个正整数W(i,j).你的任务是给每行确定一个整数row(i),每列也确定一个整数 ...

  7. Ants(二分图最佳完美匹配)

    Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6904   Accepted: 2164   Special Ju ...

  8. UVA - 1045 The Great Wall Game(二分图最佳完美匹配)

    题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...

  9. HDU 3072 (强连通分量)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3072 题目大意:为一个有向连通图加边.使得整个图全连通,有重边出现. 解题思路: 先用Tarjan把 ...

随机推荐

  1. Nginx中防盗链(下载防盗链和图片防盗链)及图片访问地址操作记录

    日常运维工作中,设置防盗链的需求会经常碰到,这也是优化网站的一个必要措施.今天在此介绍Nginx中设置下载防盗链和图片防盗链的操作~ 一.Nginx中下载防盗链的操作记录对于一些站点上的下载操作,有很 ...

  2. php安全配置记录和常见错误梳理

    通常部署完php环境后会进行一些安全设置,除了熟悉各种php漏洞外,还可以通过配置php.ini来加固PHP的运行环境,PHP官方也曾经多次修改php.ini的默认设置.下面对php.ini中一些安全 ...

  3. hadoop-mapreduce-(1)-统计单词数量

    编写map程序 package com.cvicse.ump.hadoop.mapreduce.map; import java.io.IOException; import org.apache.h ...

  4. 树的最长链-POJ 1985 树的直径(最长链)+牛客小白月赛6-桃花

    求树直径的方法在此转载一下大佬们的分析: 可以随便选择一个点开始进行bfs或者dfs,从而找到离该点最远的那个点(可以证明,离树上任意一点最远的点一定是树的某条直径的两端点之一:树的直径:树上的最长简 ...

  5. 12.24daily_scrum

    今天是平安夜,大家开心地度过一个平安夜的同时,也完成了很多软件的调试工作,我们争取在下周前完成本阶段的所有调试工作. 具体工作如下: 具体工作: 小组成员 今日任务 明日任务 工作时间 李睿琦 软件调 ...

  6. M2阶段事后总结

    设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述?我们的主要任务是将35w+个符合条件的网页,问答,文章放入数据库:爬取功能定义为以下几种:通用型爬取 ...

  7. C++编写四则运算生成程序

    1.计划方案 按照预定计划,在时限为一周时,完成该程序所需时间大致如下表: PSP2.1 Personal Software Process Stages Time Planning 计划 · Est ...

  8. Daily Scrumming* 2015.12.19(Day 11)

    一.团队scrum meeting照片 二.成员工作总结 姓名 任务ID 迁入记录 江昊 任务1090 https://github.com/buaaclubs-team/temp-front/com ...

  9. MySql修改root密码以及允许外网访问

    1.修改root密码 用SET PASSWORD命令 mysql -u root mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('n ...

  10. ajax 异步请求 代码

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...