poj 2516 Minimum Cost KM算法 最小权值匹配

本文介绍了如何使用Kuhn-Munkres(KM)算法解决poj 2516问题,重点在于理解KM算法的基本思想和优化策略。KM算法通过调整顶标使得带权二分图的相等子图具有完备匹配,最终找到最大权匹配。初始设置A[i]为最大权,B[j]为0,通过迭代修改顶标并寻找增广路径,确保A[i]+B[j]>=w[i,j],实现O(n^3)的时间复杂度。" 100114611,8708542,Unity3D 制作机器人动画教程,"['Unity', '3D动画', '游戏开发', '动画控制器']
摘要由CSDN通过智能技术生成

一开始想到了就是拆点,题目说每个人对每种goods的需求都是只有0-3,我是从这个想到的。。。

接下来就是建立模型拉。然后就是KM算法。。


#include<iostream>

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int shop[51][51];
int store[51][51];
int cost[51][51][51];
int sum1[51];
int sum2[51];
int max(int x,int y){
if(x>y)return x;
return y;
}
int min(int x,int y){
if(x>y)return y;
return x;
}
char maze[200][200];/根据题目要求建二分图的需要
int weight[200][200];///二分图中各个顶点的标号
int match[200];匹配结果
int lx[200],ly[200];记录顶点的标号
int lack;当无法增广路时应该缩小的范围
int visx[200],visy[200];//记录此次的匹配访问过的结点
int  num;/记录总共有多少个顶点
int num2;
bool dfs(int u){/找增广路,其实和最大匹配差不多
visx[u] = 1;
for(int v = 1;v<num2;++v){
if(!visy[v]){
int t = lx[u]+ly[v]-weight[u][v];
if(t==0){
visy[v] = true;
if(match[v]==-1 ||dfs(match[v]))
{
match[v] = u;
return true;
}
}
else lack = max(lack,t);///靠这个记录该缩小的范围
}
}
return false;
}
long long  KM()
{
int i,j;
for(i =1;i<num;i++){///初始化
lx[i] = 100000000;
for(j = 1;j<num2;j++)lx[i] = min(lx[i],weight[i][j]);
}
for(int i = 1;i<num2;i++)ly[i] = 0;
memset(match,-1,sizeof(match));
for(int u = 1;u<num;u++)
while(1){
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
lack = -10000000;
if(dfs(u))break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值