Kuhn_Munkres最大权匹配算法C++模板

来源:互联网 发布:西安软件公寓地址 编辑:程序博客网 时间:2024/06/07 05:11
#include <cstdio>#include <memory.h>#include <algorithm> // 使用其中的 min 函数using namespace std;const int MAX = 1024;int n; // X 的大小int weight [MAX] [MAX]; // X 到 Y 的映射(权重)int lx [MAX], ly [MAX]; // 标号bool sx [MAX], sy [MAX]; // 是否被搜索过int match [MAX]; // Y(i) 与 X(match [i]) 匹配// 初始化权重void init (int size);// 从 X(u) 寻找增广道路,找到则返回 truebool path (int u);// 参数 maxsum 为 true ,返回最大权匹配,否则最小权匹配int bestmatch (bool maxsum = true);void init (int size){// 根据实际情况,添加代码以初始化n = size;for (int i = 0; i < n; i ++)for (int j = 0; j < n; j ++)scanf ("%d", &weight [i] [j]);}bool path (int u){sx [u] = true;for (int v = 0; v < n; v ++)if (!sy [v] && lx[u] + ly [v] == weight [u] [v]){sy [v] = true;if (match [v] == -1 || path (match [v])){match [v] = u;return true;}}return false;}int bestmatch (bool maxsum){int i, j;if (!maxsum){for (i = 0; i < n; i ++)for (j = 0; j < n; j ++)weight [i] [j] = -weight [i] [j];}// 初始化标号for (i = 0; i < n; i ++){lx [i] = -0x1FFFFFFF;ly [i] = 0;for (j = 0; j < n; j ++)if (lx [i] < weight [i] [j])lx [i] = weight [i] [j];}memset (match, -1, sizeof (match));for (int u = 0; u < n; u ++)while (true){memset (sx, 0, sizeof (sx));memset (sy, 0, sizeof (sy));if (path (u))break;// 修改标号int dx = 0x7FFFFFFF;for (i = 0; i < n; i ++)if (sx [i])for (j = 0; j < n; j ++)if(!sy [j])dx = min (lx[i] + ly [j] - weight [i] [j], dx);for (i = 0; i < n; i ++){if (sx [i])lx [i] -= dx;if (sy [i])ly [i] += dx;}}int sum = 0;for (i = 0; i < n; i ++)sum += weight [match [i]] [i];if (!maxsum){sum = -sum;for (i = 0; i < n; i ++)for (j = 0; j < n; j ++)weight [i] [j] = -weight [i] [j]; // 如果需要保持 weight [ ] [ ] 原来的值,这里需要将其还原}return sum;}int main(){int n;scanf ("%d", &n);init (n);int cost = bestmatch (true);printf ("%d \n", cost);for (int i = 0; i < n; i ++){printf ("Y %d -> X %d \n", i, match [i]);}system("pause");return 0;}/*53 4 6 4 96 4 5 3 87 5 3 4 26 3 2 2 58 4 5 4 7//执行bestmatch (true) ,结果为 29*//*57 6 4 6 14 6 5 7 23 5 7 6 84 7 8 8 52 6 5 6 3//执行 bestmatch (false) ,结果为 21*/

0 0