dfs,bfs的二分匹配模板(模板题hdu1150)
如果不懂匈牙利算法,请点击:该趣味算法http://blog.csdn.net/dark_scope/article/details/8880547
模板:
//DFS版本下的二分匹配算法
http://paste.ubuntu.net/16122581/
#include<cstdio>
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<math.h>
#include<queue>
#include<stdlib.h>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
//DFS版本下的二分匹配算法
const int MAXN = 300; //最大顶点数
bool bmap[MAXN][MAXN]; //二分图
bool bmask[MAXN]; //寻找增广路径的标志数组
int nx,ny; //nx为左顶点的个个数,ny为右顶点的个数
int cx[MAXN]; //cx[i]表示左集合i顶点所匹配到的右集合的顶点的序号。
int cy[MAXN]; //cy[i]表示右集合i顶点所匹配到的左集合的顶点的序号。
int k;
int findpath(int u)
{
int i;
for(i=0;i<ny;i++) //扫描每个妹子
{
//如果【有暧昧】并且【还没有标记过】
//这里标记的意思是这次查找【曾】试图改变过该妹子的归属问题
//但是没有成功,所以就不用瞎费工夫了
if(bmap[u][i]&&!bmask[i])
{
bmask[i]=1;
if(cy[i]==-1||findpath(cy[i])) //名花无主 或者 能腾出个位置来,这里使用递归
{
cy[i]=u;
cx[u]=i;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int res=0; //有多少对
int i,j;
for(int i=0;i<nx;i++)
cx[i]=-1;
for(int i=0;i<ny;i++)
cy[i]=-1;
for(int i=0;i<nx;i++) //为男生找配偶
{
if(cx[i]==-1)
{
for(int j=0;j<ny;j++) //这个在每一步中清空
bmask[j]=0;
res+=findpath(i);
}
}
return res;
}
int main()
{
while(~scanf("%d",&nx)&&nx)
{
scanf("%d%d",&ny,&k);
int x;
memset(bmap,0,sizeof(bmap));
int a,b;
for(int i=0;i<k;i++)
{
scanf("%d%d%d",&x,&a,&b);
if(a>0&&b>0)
bmap[a][b]=1;
}
int ans=MaxMatch();
printf("%d\n",ans);
}
return 0;
}
/*
2 2 3
0 1 1
1 2 1
2 2 2
*/
//BFS版本下的二分匹配算法
http://paste.ubuntu.net/16122732/
#include<cstdio>
#include<string.h>
#include<iostream>
using namespace std;
typedef long long LL;
//BFS版本下的二分匹配算法
//我觉得DFS的很好理解,所以我觉得套用DFS的讲,可能有偏差;
const int MAXN = 1000; //最大顶点数
int bmap[MAXN][MAXN]; //二分图
int cx[MAXN]; //cx[i]表示左集合i顶点所匹配到的右集合的顶点的序号。
int cy[MAXN]; //cy[i]表示右集合i顶点所匹配到的左集合的顶点的序号。
int nx,ny,k; //nx为左顶点的个个数,ny为右顶点的个数
int bmask[MAXN]; //寻找增广路径的标志数组
int que[MAXN]; //队列保存扩展顶点
int pre[MAXN]; //记录前置顶点
int MaxMatch()
{
int res=0;
int qs,qe;
memset(cx,-1,sizeof(cx));
memset(cy,-1,sizeof(cy));
memset(bmask,-1,sizeof(bmask));
for(int i=0;i<nx;i++)
{
if(cx[i]==-1) //为男的寻找配偶
{
qs=qe=0; //队列初始化
que[qe++]=i;
pre[i]=-1;
bool flag=0;
while(qs<qe&&!flag)
{
int u=que[qs];
for(int v=0;v<ny&&!flag;v++)
{
if(bmap[u][v]&&bmask[v]!=i) //如果有关系,但是这个关系并不是给我们要配对的男生
{
bmask[v]=i; //但是...该男子强行拿过来作为妻子
que[qe++]=cy[v]; //所以女生本来的丈夫就很伤了
if(cy[v]>=0) //如果那个人有丈夫的话,就用pre记录前置节点
{
pre[cy[v]]=u;
}
else //但是该女子没有丈夫,那就是刚刚好
{
flag=1; //OK解决问题
int d=u,e=v;
while(d!=-1) //然后这就是类似于DFS算法中的回溯,这建立了改男子配对下的状态是什么样子的。
{
int t=cx[d];
cx[d]=e;cy[e]=d;
d=pre[d];e=t;
}
}
}
}
qs++;
}
if(cx[i]!=-1) //有多少配对的男子,就加几个
{
res++;
}
}
}
return res;
}
int main()
{
while(~scanf("%d",&nx)&&nx)
{
scanf("%d%d",&ny,&k);
int x;
memset(bmap,0,sizeof(bmap));
int a,b;
for(int i=0;i<k;i++)
{
scanf("%d%d%d",&x,&a,&b);
if(a>0&&b>0)
bmap[a][b]=1;
}
int ans=MaxMatch();
printf("%d\n",ans);
}
return 0;
}
dfs,bfs的二分匹配模板(模板题hdu1150)的更多相关文章
- hdu 5046 二分+DLX模板
http://acm.hdu.edu.cn/showproblem.php?pid=5046 n城市建k机场使得,是每个城市最近机场的距离的最大值最小化 二分+DLX 模板题 #include < ...
- POJ:Dungeon Master(三维bfs模板题)
Dungeon Master Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16748 Accepted: 6522 D ...
- POJ-2251 Dungeon Master (BFS模板题)
You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of un ...
- POJ 1741.Tree and 洛谷 P4178 Tree-树分治(点分治,容斥版) +二分 模板题-区间点对最短距离<=K的点对数量
POJ 1741. Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 34141 Accepted: 11420 ...
- hdu1242 又又又是逃离迷宫(bfs模板题)
题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1242/ 这次的迷宫是有守卫的,杀死一个守卫需要花费1个单位的时间,所以以走的步数为深度,在每一层进行搜索,由于走 ...
- 用一道模板题理解多源广度优先搜索(bfs)
题目: //多元广度优先搜索(bfs)模板题详细注释题解(c++)class Solution { int cnt; //新鲜橘子个数 int dis[10][10]; //距离 int dir_x[ ...
- xdu_1048:二分匹配模板测试
二分匹配的模板题,这里用网络流模板(见刘汝佳<算法竞赛入门经典·训练指南>P359 Dinic算法)做. 将男女生均看做网络上的节点,题中给出的每个"关系"看做一条起点 ...
- HDU 4280:Island Transport(ISAP模板题)
http://acm.hdu.edu.cn/showproblem.php?pid=4280 题意:在最西边的点走到最东边的点最大容量. 思路:ISAP模板题,Dinic过不了. #include & ...
- POJ 1985 Cow Marathon (模板题)(树的直径)
<题目链接> 题目大意: 给定一颗树,求出树的直径. 解题分析:树的直径模板题,以下程序分别用树形DP和两次BFS来求解. 树形DP: #include <cstdio> #i ...
随机推荐
- SolidEdge如何快速绘制并完全定义槽型孔
如果你点击A之后形成的圆弧不是你想要的 你试着换个方向,如下图所示 有时候只有一个方形可以形成你要的半圆
- Qt在线技术交流之OpenGL、Quick以及所经历项目开发心得分享
时间:3月25日晚上7:30 主题:Qt在线技术交流之OpenGL.Quick以及所经历项目开发心得分享 直播:http://qtdream.com 主页.全民TV,可能会加上其他的直播平台进行转播 ...
- Java 兔子问题(斐波那契数列)扩展篇
Java兔子问题(斐波那契数列)扩展篇 斐波那契数列指的是这样一个数列 0, 1, 1, 2,3, 5, 8, 13, 21, 34, 55, 89, 144, ...对于这个数列仅仅能说将兔子生产周 ...
- Linux下mount FreeBSD分区
假设须要从第二块硬盘复制文件.该硬盘格式化为UFS 2文件系统.怎样mount 由FreeBSD创建的UFS 2文件系统到Ubuntu系统上呢? UFS文件系统广泛的使用在不同的操作系统(比如:HP- ...
- 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 工作队列是下半部的第二种将工作推后运行形式.和软中断.task ...
- 01背包+卡精度 Hdu 2955
<span style="color:#3333ff;">/* ---------------------------------------------------- ...
- 翻译:A Tutorial on the Device Tree (Zynq) -- Part III
A Tutorial on the Device Tree (Zynq) -- Part III 定义外设 可能你读本文是为了给你的设备写一个Linux驱动,在这方面要推荐著名的<Linux D ...
- dubbo配置指南
dubbo配置指南 SLA配置在此完成!Service Layer Agreement ApplicationConfig 应用配置,用于配置当前应用信息,不管该应用是提供者还是消费者. Regist ...
- Flume-ng-sdk源码分析
Flume 实战(2)--Flume-ng-sdk源码分析 - mumuxinfei - 博客园 http://www.cnblogs.com/mumuxinfei/p/3823266.html
- Marking as slave lost.
Spark on Yarn提交任务时报ClosedChannelException解决方案_服务器应用_Linux公社-Linux系统门户网站 http://www.linuxidc.com/Linu ...