您的位置:首页 > 编程语言 > C语言/C++

匈牙利算法(二分图最大匹配)

2017-11-03 17:04 232 查看
距离NOIP2017还有7天,那么我们就准备一些模板来看看吧!

今天复习一下匈牙利算法!

值得一提的是,匈牙利算法求出的二分图最大匹配就是最小点覆盖。这样我们可以做一个“战略游戏”(Luogu P2016)的题目。

模板的具体解释见代码:(Luogu P3386)

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int i,j,k,m,n,e;
int hd[2001],temp;
int mat[2001],b[2001];
int ans;

struct data
{
int y,nxt;
}a[2000001];

int r()
{
int aans=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
aans*=10;
aans+=ch-'0';
ch=getchar();
}
return aans*f;
}

void add(int xx,int yy)
{
a[++temp].y=yy;
a[temp].nxt=hd[xx];
hd[xx]=temp;
}

bool dfs(int x)
{
for(int p=hd[x];p;p=a[p].nxt)
{
int son=a[p].y;
if(!b[son])
{
b[son]=1;//是否遍历过
if(!mat[son]||dfs(mat[son]))//如果目标搭档没有搭档或者目标搭档可以被抢走
{
mat[son]=x;//那么把让这两个成为一对
mat[x]=son;
return 1;//返回当前可行
}
}
}
return 0;//返回不可行
}

int main()
{
//  freopen("in.txt","r",stdin);
n=r(),m=r(),e=r();
int u,v;
for(i=1;i<=e;i++)
{
u=r(),v=r();
if(v<=m&&u<=n&&u>0&&v>0)//判断数据
{add(u,v+n);//建双向边
add(v+n,u);}
}

for(i=1;i<=n;i++)
{
if(!mat[i])//是否有搭档
{
memset(b,0,sizeof(b));
if(dfs(i))
ans++;
}
}

cout<<ans;

return 0;
}
/*
3 4 6
1 1
1 2
1 3
2 2
2 4
3 1
3 3
*/


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c语言 算法 战略 游戏