带权二分图匹配(KM算法)

简介: 带权二分图匹配(KM算法)

Problem Description

传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子。

这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子。

另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).


Input

输入数据包含多组测试用例,每组数据的第一行输入n,表示房子的数量(也是老百姓家的数量),接下来有n行,每行n个数表示第i个村名对第j间房出的价格(n<=300)。


Output

请对每组数据输出最大的收入值,每组的输出占一行。


Sample Input

2

100 10

15 23


Sample Output

123


KM算法

https://blog.csdn.net/guoyangfan_/article/details/83064499

#include <bits/stdc++.h>
using namespace std;
const int maxn = 305;
int w[maxn][maxn];
int lx[maxn], ly[maxn];
int visx[maxn], visy[maxn];
int match[maxn];
int n, delta;
const int inf = 1<<30;
int dfs(int u) {
  visx[u] = 1;/*当前点(x)参与了这次dfs,将其标记*/
  for (int i = 1; i <= n; i++) {/*由题意,我们要选择所有可能的人组队*/
    if (!visy[i]) {/*如果要去匹配的点在本次操作中还没有操作过*/
      int tmp = lx[u] + ly[i] - w[u][i];
      if (tmp == 0) {
        visy[i] = 1;
        if (match[i] == 0 || dfs(match[i])) {
          match[i] = u;
          return 1;/*可以找到在当前顶标的其他匹配点*/
        }
      } else if (tmp > 0){
        delta = min(delta, tmp);/*找不到了,试图减小参与本次dfs的顶标*/
      }
    }
  }
  return 0;
}
void KM() {
  memset(match, 0, sizeof(match));
  memset(lx, 0, sizeof(lx));
  memset(ly, 0, sizeof(ly));
  for (int i = 1; i <= n; i++) 
    for (int j = 1; j <= n; j++) 
      lx[i] = max(lx[i], w[i][j]);
  for (int i = 1; i <= n; i++) {
    while (1) {
      memset(visx, 0, sizeof(visx));
      memset(visy, 0, sizeof(visy)); /*每轮操作的预处理,表示在当前dfs中,是否操作过*/
      delta = inf;
      if (dfs(i)) break;/*如果可以将当前点之前的点的匹配点换掉且顶标不变,那么我们直接跳过下面的步骤,寻找下一个点的匹配方案*/
      for (int j = 1; j <= n; j++) {/*我们根据步骤操作,左边节点-date,右边节点+date*/
        if (visx[j]) lx[j] -= delta;
        if (visy[j]) ly[j] += delta;
      }
    }
  }
}
int main() {
  while (~scanf("%d", &n)) {
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        scanf("%d", &w[i][j]);
      }
    }
    KM();
    int ans = 0;
    for (int i = 1; i <= n; i++) {
      ans += w[match[i]][i];
    }
    printf("%d\n", ans); 
  }
  return 0;
}
相关文章
|
算法 PHP
|
21天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
1月前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于MSER和HOG特征提取的SVM交通标志检测和识别算法matlab仿真
### 算法简介 1. **算法运行效果图预览**:展示算法效果,完整程序运行后无水印。 2. **算法运行软件版本**:Matlab 2017b。 3. **部分核心程序**:完整版代码包含中文注释及操作步骤视频。 4. **算法理论概述**: - **MSER**:用于检测显著区域,提取图像中稳定区域,适用于光照变化下的交通标志检测。 - **HOG特征提取**:通过计算图像小区域的梯度直方图捕捉局部纹理信息,用于物体检测。 - **SVM**:寻找最大化间隔的超平面以分类样本。 整个算法流程图见下图。
|
6天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
8天前
|
算法 调度
基于遗传模拟退火混合优化算法的车间作业最优调度matlab仿真,输出甘特图
车间作业调度问题(JSSP)通过遗传算法(GA)和模拟退火算法(SA)优化多个作业在并行工作中心上的加工顺序和时间,以最小化总完成时间和机器闲置时间。MATLAB2022a版本运行测试,展示了有效性和可行性。核心程序采用作业列表表示法,结合遗传操作和模拟退火过程,提高算法性能。
|
8天前
|
存储 算法 决策智能
基于免疫算法的TSP问题求解matlab仿真
旅行商问题(TSP)是一个经典的组合优化问题,目标是寻找经过每个城市恰好一次并返回起点的最短回路。本文介绍了一种基于免疫算法(IA)的解决方案,该算法模拟生物免疫系统的运作机制,通过克隆选择、变异和免疫记忆等步骤,有效解决了TSP问题。程序使用MATLAB 2022a版本运行,展示了良好的优化效果。
|
8天前
|
机器学习/深度学习 算法 芯片
基于GSP工具箱的NILM算法matlab仿真
基于GSP工具箱的NILM算法Matlab仿真,利用图信号处理技术解析家庭或建筑内各电器的独立功耗。GSPBox通过图的节点、边和权重矩阵表示电气系统,实现对未知数据的有效分类。系统使用MATLAB2022a版本,通过滤波或分解技术从全局能耗信号中提取子设备的功耗信息。
|
8天前
|
机器学习/深度学习 算法 5G
基于MIMO系统的SDR-AltMin混合预编码算法matlab性能仿真
基于MIMO系统的SDR-AltMin混合预编码算法通过结合半定松弛和交替最小化技术,优化大规模MIMO系统的预编码矩阵,提高信号质量。Matlab 2022a仿真结果显示,该算法能有效提升系统性能并降低计算复杂度。核心程序包括预编码和接收矩阵的设计,以及不同信噪比下的性能评估。
24 3
|
19天前
|
人工智能 算法 数据安全/隐私保护
基于遗传优化的SVD水印嵌入提取算法matlab仿真
该算法基于遗传优化的SVD水印嵌入与提取技术,通过遗传算法优化水印嵌入参数,提高水印的鲁棒性和隐蔽性。在MATLAB2022a环境下测试,展示了优化前后的性能对比及不同干扰下的水印提取效果。核心程序实现了SVD分解、遗传算法流程及其参数优化,有效提升了水印技术的应用价值。
|
20天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于贝叶斯优化CNN-LSTM网络的数据分类识别算法matlab仿真
本项目展示了基于贝叶斯优化(BO)的CNN-LSTM网络在数据分类中的应用。通过MATLAB 2022a实现,优化前后效果对比明显。核心代码附带中文注释和操作视频,涵盖BO、CNN、LSTM理论,特别是BO优化CNN-LSTM网络的batchsize和学习率,显著提升模型性能。