这篇文章主要介绍了二分图匹配实例代码及整理的相关资料,这里提供了三种方法包括匈牙利算法,公里算法,多重匹配,需要的朋友可以参考下
二分图匹配实例代码及整理
1、匈牙利算法
HDU 1150
# includestdio.h
#includestring.h
#包含算法
使用命名空间标准
int m,n,k;
int vis[105];
int mpt[105][105];
int use[105];
(同Internationalorganizations)国际组织匈牙利(整数x)
{
for(int I=1;im;我)
{
if(vis[i]==0mpt[x][i]==1)
{
vis[I]=1;
如果(使用[i]==-1 | |匈牙利(使用[我]))
{
使用[I]=x;
返回1;
}
}
}
返回0;
}
int main()
{
while(scanf(%d ,n)!=EOF,n)
{
scanf(%d%d ,m,k);
int a,b,c;
memset(mpt,0,sizeof(mpt));
for(int I=1;I=k;我)
{
scanf(%d%d%d ,c,a,b);
mpt[a][b]=1;
}
int ans=0;
memset(use,-1,sizeof(use));
for(int I=1;在;我)
{
如果(匈牙利(一))
{
美国国家标准(American National Standards的缩写)
}
memset(vis,0,sizeof(vis));
}
printf(%dn ,ans);
}
返回0;
}
2、公里算法
HDU 2255
看了很多资料都还不是很懂、先贴别人的模板
#includeiostream
#includecstdio
# includecstring
#包括限制
#包含算法
使用命名空间标准
#定义N 310
int map[N][N];
bool visitx[N],visity[N];
int lx[N],ly[N];
int match[N];
int n;
布尔匈牙利语(int u) //匈牙利算法
{
visitx[u]=true;
for(int I=0;I n;我)
{
如果(!访问LX[u]ly[I]==地图[u][I])
{
visity[I]=true;
if(match[i]==-1 ||匈牙利(匹配[i]))
{
match[I]=u;
返回真实的
}
}
}
返回错误的
}
void KM_perfect_match()
{
内部温度;
memset(lx,0,sizeof(LX));//初始化顶标
memset(ly,0,sizeof(ly));//ly[i]为0
for(int I=0;I n;i) //lx[i]为权值最大的边
for(int j=0;j n;j)
lx[i]=max(lx[i],map[I][j]);
for(int I=0;I n;i) //对n个点匹配
{
while(1)
{
memset(visitx,false,sizeof(visitx));
memset(visity,false,sizeof(visity));
如果(匈牙利(一))//匹配成功
打破;
else //匹配失败,找最小值
{
temp=INT _ MAX
for(int j=0;j n;j) //x在交错树中
if(visitx[j])
for(int k=0;k n;k) //y在交错树外
如果(!visity[k]temp LX[j]ly[k]-map[j][k])
temp=LX[j]ly[k]-map[j][k];
for(int j=0;j n;j) //更新顶标
{
if(visitx[j])
LX[j]-=temp;
if(visity[j])
ly[j]=temp;
}
}
}
}
}
int main()
{
国际事务
while(scanf(%d ,n)!=EOF)
{
ans=0;
memset(match,-1,sizeof(match));
for(int I=0;I n;我)
for(int j=0;j n;j)
scanf(%d ,map[I][j]);
KM _完美_匹配();
for(int I=0;I n;i) //权值相加
ans=map[match[I]][I];
printf(%dn ,ans);
}
返回0;
}
3、多重匹配
HDU 3605逃脱
# includestdio.h
#includestring.h
#包含算法
使用命名空间标准
int n,m;
int num[15];
int mpt[100005][15];
int vis[15];
int use[15];
int DP[15][100005];
(同Internationalorganizations)国际组织匈牙利(整数x)
{
for(int I=1;I=m;我)
{
if(vis[i]==0mpt[x][i]==1)
{
vis[I]=1;
如果(使用num[I]//满足条件
{
DP[I][use[I]]=x;
返回1;
}
//不满足则寻找增广路
for(int j=0;juse[I];j )//看能否回溯一个出去
{
如果(匈牙利(dp[i][j])
{
DP[I][j]=x;
返回1;
}
}
}
}
返回0;
}
int main()
{
while(scanf(%d%d ,n,m)!=EOF)
{
for(int I=1;I=n;我)
{
for(int j=1;j=m;j)
{
scanf(%d ,mpt[I][j]);
}
}
for(int I=1;I=m;我)
scanf(%d ,num[I]);
int ans=0;
memset(use,0,sizeof(use));
for(int I=1;I=n;我)
{
memset(vis,0,sizeof(vis));
如果(!匈牙利(一))
{
ans=1;
打破;
}
}
如果(ans==0)
{
printf( YES n );
}
else printf( NO n );
}
返回0;
}
以上是二分匹配的实现代码。如有问题,欢迎留言,或前往本站社区交流讨论。感谢阅读,希望能帮到你,也感谢你对本站的支持!