运动员最佳匹配问题 KM算法:带权二分图匹配
题面:
羽毛球队有男女运动员各n人。给定2 个n×n矩阵P和Q。P[i][j]是男运动员i和女运动员j配对组成混合双打的男运动员竞赛优势;Q[i][j]是女运动员i和男运动员j配合的女运动员竞赛优势。由于技术配合和心理状态等各种因素影响,P[i][j]不一定等于Q[j][i]。男运动员i和女运动员j配对组成混合双打的男女双方竞赛优势为P[i][j]*Q[j][i]。设计一个算法,计算男女运动员最佳配对法,使各组男女双方竞赛优势的总和达到最大。
题解:
看完题很容易发现这就是一个带权二分图匹配,
那么有两种选择:KM算法,费用流,
由于KM算法时间复杂度更优,这里选择KM算法,
以P[i][j]*Q[j][i]为边权直接匹配就好了
我是当KM算法模板做的,,,,
KM算法网上讲解也蛮多的,这里就不写了(其实是懒得画图)
这里运动员的数量很少,显然用邻接矩阵更合适,
匈牙利算法其实也可以看做是权值为1的带权二分图,
KM算法中也需要用到匈牙利,
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 24
int n,ans;
int tmp[AC][AC],s[AC][AC];
int vis[AC],z[AC];//vis = boy ,z = girl
int slack[AC];//对应的男生至少要降低多少权值
int link[AC],power_g[AC],power_b[AC];
/*km算法模板题*/ inline void upmax(int &a,int b)
{
if(b > a) a = b;
} inline void upmin(int &a,int b)
{
if(b < a) a = b;
} void pre()
{
scanf("%d",&n);
for(R i=;i<=n;i++)
for(R j=;j<=n;j++)
scanf("%d",&tmp[i][j]);
for(R i=;i<=n;i++)
for(R j=;j<=n;j++)
{
scanf("%d",&s[i][j]);
s[i][j] *= tmp[j][i];//求出每条边的权值
upmax(power_g[i],s[i][j]);//初始权值为所有权值里面最大的那个
}
} bool dfs(int x)
{
int now;
z[x]=true;
for(R i=;i<=n;i++)
{
if(vis[i]) continue;//每个男生只能访问一次
now=power_g[x] + power_b[i] - s[x][i];//获取权值和与边权之间的差距(一般会为正?)
if(!now)//如果刚好相等就连了
{
vis[i]=true;
if(!link[i] || dfs(link[i]))//如果对方还没有被匹配or之前那个人可以换走的话
{//因为要换走自己这边的人,所以是dfs(link[i])啊
link[i]=x;//就连上
return true;//其实这部分就是匈牙利
}
}
else upmin(slack[i],now);//不然就获取最小差距,以便调整权值时用
}
return false;//要是前面一直没有被匹配上
} void KM()
{
int x;
for(R i=;i<=n;i++)
{
memset(slack,,sizeof(slack));//因为要获取最小限度,所以初始化为极大值
while()//为什么一定要匹配满?貌似是题目要求,,,,
{
memset(vis,,sizeof(vis));
memset(z,,sizeof(z));
if(dfs(i)) break;//如果直接就配上了那就算了
x=INT_MAX;
for(R j=;j<=n;j++)
if(!vis[j]) upmin(x,slack[j]);//获取整张图的最小限度
for(R j=;j<=n;j++)
{//给涉及到的点修改权值
if(z[j]) power_g[j] -= x;//error!!!不要搞反了,是给女生降低,男生提高
if(vis[j]) power_b[j] += x;
else slack[j] -= x;//因为对面降低了,所以差距也小了
}
} }
for(R i=;i<=n;i++)
ans+=s[link[i]][i];//枚举男生,因为link[i]存的是男生对应的女生,所以只有男生才能获取到女生,反之不行
printf("%d\n",ans);
} int main()
{
// freopen("in.in","r",stdin);
pre();
KM();
// fclose(stdin);
return ;
}
运动员最佳匹配问题 KM算法:带权二分图匹配的更多相关文章
- KM算法 带权二分匹配 O(n^3)
#include<cstdio> #include<cstdlib> #include<cstring> #include<string> #inclu ...
- POJ 2195 Going Home (带权二分图匹配)
POJ 2195 Going Home (带权二分图匹配) Description On a grid map there are n little men and n houses. In each ...
- 费用流模板(带权二分图匹配)——hdu1533
/* 带权二分图匹配 用费用流求,增加源点s 和 汇点t */ #include<bits/stdc++.h> using namespace std; #define maxn 1000 ...
- POJ 2195 Going Home | 带权二分图匹配
给个地图有人和房子 保证人==房子,每个人移动到房子处需要花费曼哈顿距离的代价 问让人都住在房子里最小代价 显然是个带权二分图最大匹配 转化成以一个网络,规定w是容量,c是代价 1.S向人连边,w=1 ...
- hdu5045:带权二分图匹配
题目大意 : n个人 做m道题,其中 每连续的n道必须由不同的人做 已知第i人做出第j题的概率为pij,求最大期望 思路:考虑每连续的n道题 都要n个人来做,显然想到了带权的二分图匹配 然后就是套模板 ...
- Glorious Brilliance (最短路 + 带权二分图匹配)
这是一道代码大题.一开始读错题意了,然后理解成直接看上去的那种相邻,然后想不通好久!!! 把不同联通的图分离出来,然后先预处理一下形成之后的相邻图的状态,然后根据01确定哪一些是需要更换状态的,然后建 ...
- [NOI2012]美食节——费用流(带权二分图匹配)+动态加边
题目描述 小M发现,美食节共有n种不同的菜品.每次点餐,每个同学可以选择其中的一个菜品.总共有m个厨师来制作这些菜品.当所有的同学点餐结束后,菜品的制作任务就会分配给每个厨师.然后每个厨师就会同时开始 ...
- [HAOI2008]移动玩具(状压&带权二分图)
题目描述 • 一个 4 × 4 的 0/1 矩阵 • 每次可以交换相邻两个元素 • 求从初始状态到目标状态的最小交换次数 输入格式 前四行,每行一个长为 4 的 0/1 字符串,描述初始状态. 后四行 ...
- KM(Kuhn-Munkres)算法求带权二分图的最佳匹配
KM(Kuhn-Munkres)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...
随机推荐
- 7、Java并发编程:深入剖析ThreadLocal
Java并发编程:深入剖析ThreadLocal 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理.首先,本文先谈一下对ThreadLoc ...
- Mysql 8.0.* zip版本 windows安装
一,MySQL8.0.*zip版本安装步骤. 1,下载 https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.15-winx64.zip 注现 ...
- 第四篇 与Flask相关的插件(flask-session、wtforms)
公司中使用SQL的种方式: 1. 写Django:ORM(关系对象映射), 2. 写Flask和其他:有两种方式: (1) 原生SQL:使用原生SQL有两种选择: A. pymysql (python ...
- 在nginx环境下,直接用域名访问(首页)
①: server { listen 80; server_name www.njm1.com; location = / { #=/规则可以直接访问域名.如:www.njm1.com.跳转到http ...
- Java开发工程师(Web方向) - 03.数据库开发 - 期末考试
期末考试 编程题 本编程题包含4个小题,覆盖知识点从基础的JDBC.连接池到MyBatis. 1(10分) 有一款在线教育产品“天天向上”主要实现了在手机上查看课程表的功能.该产品的后端系统有一张保存 ...
- 小程序解析html和富文本编辑内容【亲测有效】
首先去 https://github.com/icindy/wxParse 下载wxParse,只拷贝wxParse文件夹即可. 1.引入wxss @import "../../util/w ...
- Machine Learning笔记整理 ------ (五)决策树、随机森林
1. 决策树 一般的,一棵决策树包含一个根结点.若干内部结点和若干叶子结点,叶子节点对应决策结果,其他每个结点对应一个属性测试,每个结点包含的样本集合根据属性测试结果被划分到子结点中,而根结点包含样本 ...
- LeetCode 386——字典序的第 K 小数字
1. 题目 2. 解答 字典序排数可以看做是第一层节点分别为 1-9 的十叉树,然后我们在树上找到第 K 小的数字即可.因此,我们需要分别统计以 1-9 为根节点的每个树的节点个数.如果 K 小于当前 ...
- 如何让thinkpad X1C 用U盘 安装上专业版win10
1 BIOS内置了文件 会导致win10 iso默认装家庭版 2 给iso 的resouse 目录中增加文件ei.cfg 3 内容如下 [EditionID]Professional[Channel] ...
- [zt]手把手教你写对拍程序(PASCAL)
谁适合看这篇文章? ACMERS,OIERS或其它参加算法竞赛或需要算法的人 对操作系统并不太熟悉的人 不会写对拍的人 在网上找不到一个特别详细的对拍样例的人 不嫌弃我写的太低幼的人 前言 在NOIP ...