运动员最佳匹配问题 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)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...
随机推荐
- 函数返回const,以便控制访问
#include <stdio.h> class const_out_parameter{ private: ]; public: int* const_out_parameter_tes ...
- VS Help Viewer 显示内容为HTML源码的问题
万恶的IE10 为了学习,安装了一套Windows Server 2012+SQL 2012+VS 2012的环境,整体感觉还不错,只是在使用Help Viewer查看帮助的时候,发现显示内容居然为H ...
- centos7系统配置系统用户基于ssh的google身份验证
最近也是服务器各种被入侵,所以在安全上,要万分注意,特此记录,借助google的身份验证插件,获取动态验证码完成ssh登陆. OS: centos7 安装配置: 1. 安装epel源 yum -y i ...
- 「日常训练」Skills(Codeforce Round #339 Div.2 D)
题意(CodeForces 614D) 每个人有\(n(n\le 10^5)\)个技能,技能等级都在\([0,10^9]\)的范围,每个技能有一个当前等级,所有技能的最高等级都为A.一个人的力量被记做 ...
- RabbitMQ基础教程之使用进阶篇
RabbitMQ基础教程之使用进阶篇 相关博文,推荐查看: RabbitMq基础教程之安装与测试 RabbitMq基础教程之基本概念 RabbitMQ基础教程之基本使用篇 I. 背景 前一篇基本使用篇 ...
- Xpath语法&示例
一.选取节点常用的路径表达式: 表达式 描述 实例 nodename 选取nodename节点的所有子节点 xpath(‘//div’) 选取了div节点的所有子节点 / 从根节点选取 xpath ...
- 用IDEA编写spark的WordCount
我习惯用Maven项目 所以用IDEA新建一个Maven项目 下面是pom文件 我粘上来吧 <?xml version="1.0" encoding="UTF-8& ...
- 【WXS数据类型】Function
属性: 名称 值类型 说明 [Function].constructor [String] 返回值为“Function”,表示类型的结构字符串 [Function].length [Number] 返 ...
- 【20180807模拟测试】T2 box
[问题描述] 有个桌子长 R 宽 C,被分为 R*C 个小方格.其中,一些方格上有箱子,一些方格上有按 钮,一些方格上有障碍物,一些方格上是空地.现在有个任务,需要把所有箱子推到这些按 钮上面.箱子有 ...
- POJ 3046
题目大意:蚂蚁牙黑,蚂蚁牙红:有A只蚂蚁,来自T个家族,分别记为ant[i]个.同一个家族的蚂蚁长得一样,但是不同家族的蚂蚁牙齿颜色不同.任取n只蚂蚁(S <= n <= B),求能组成几 ...