KM算法 PK 最小费用最大流

用到了KM算法 ,发现自己没有这个模板,搜索学习一下上海大学final大神,http://www.cnblogs.com/kuangbin/p/3228861.html

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 #include <iostream>
 5 using namespace std;
 6
 7 /*  KM算法
 8  *   复杂度O(nx*nx*ny)
 9  *  求最大权匹配
10  *   若求最小权匹配,可将权值取相反数,结果取相反数
11  *  点的编号从0开始
12  */
13 const int N = 310;
14 const int INF = 0x3f3f3f3f;
15 int nx,ny;//两边的点数
16 int g[N][N];//二分图描述
17 int linker[N],lx[N],ly[N];//y中各点匹配状态,x,y中的点标号
18 int slack[N];
19 bool visx[N],visy[N];
20
21 bool DFS(int x)
22 {
23     visx[x] = true;
24     for(int y = 0; y < ny; y++)
25     {
26         if(visy[y])continue;
27         int tmp = lx[x] + ly[y] - g[x][y];
28         if(tmp == 0)
29         {
30             visy[y] = true;
31             if(linker[y] == -1 || DFS(linker[y]))
32             {
33                 linker[y] = x;
34                 return true;
35             }
36         }
37         else if(slack[y] > tmp)
38             slack[y] = tmp;
39     }
40     return false;
41 }
42 int KM()
43 {
44     memset(linker,-1,sizeof(linker));
45     memset(ly,0,sizeof(ly));
46     for(int i = 0;i < nx;i++)
47     {
48         lx[i] = -INF;
49         for(int j = 0;j < ny;j++)
50             if(g[i][j] > lx[i])
51                 lx[i] = g[i][j];
52     }
53     for(int x = 0;x < nx;x++)
54     {
55         for(int i = 0;i < ny;i++)
56             slack[i] = INF;
57         while(true)
58         {
59             memset(visx,false,sizeof(visx));
60             memset(visy,false,sizeof(visy));
61             if(DFS(x))break;
62             int d = INF;
63             for(int i = 0;i < ny;i++)
64                 if(!visy[i] && d > slack[i])
65                     d = slack[i];
66             for(int i = 0;i < nx;i++)
67                 if(visx[i])
68                     lx[i] -= d;
69             for(int i = 0;i < ny;i++)
70             {
71                 if(visy[i])ly[i] += d;
72                 else slack[i] -= d;
73             }
74         }
75     }
76     int res = 0;
77     for(int i = 0;i < ny;i++)
78         if(linker[i] != -1)
79             res += g[linker[i]][i];
80     return res;
81 }
82 //HDU 2255
83 int main()
84 {
85     int n;
86     while(scanf("%d",&n) == 1)
87     {
88         for(int i = 0;i < n;i++)
89             for(int j = 0;j < n;j++)
90                 scanf("%d",&g[i][j]);
91         nx = ny = n;
92         printf("%d\n",KM());
93     }
94     return 0;
95 }

end

时间: 2024-10-05 15:42:49

KM算法 PK 最小费用最大流的相关文章

hdu 1533 Going Home 最小费用最大流

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1533 On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertically, to an adjacent point. For each little man, you need

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直

hdu 3488(KM算法||最小费用最大流)

Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 2925    Accepted Submission(s): 1407 Problem Description In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000

hdoj 1533 Going Home 【最小费用最大流】【KM入门题】

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3443    Accepted Submission(s): 1763 Problem Description On a grid map there are n little men and n houses. In each unit time, every

hdu 1533(最小费用最大流)

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4223    Accepted Submission(s): 2178 Problem Description On a grid map there are n little men and n houses. In each unit time, every l

【进阶——最小费用最大流】hdu 1533 Going Home (费用流)Pacific Northwest 2004

题意: 给一个n*m的矩阵,其中由k个人和k个房子,给每个人匹配一个不同的房子,要求所有人走过的曼哈顿距离之和最短. 输入: 多组输入数据. 每组输入数据第一行是两个整型n, m,表示矩阵的长和宽. 接下来输入矩阵. 输出: 输出最短距离. 题解: 标准的最小费用最大流算法,或者用KM算法.由于这里是要学习费用流,所以使用前者. 最小费用最大流,顾名思义,就是在一个网络中,不止存在流量,每单位流量还存在一个费用.由于一个网络的最大流可能不止一种,所以,求出当前网络在流量最大的情况下的最小花费.

[hdu1533]二分图最大权匹配 || 最小费用最大流

题意:给一个n*m的地图,'m'表示人,'H'表示房子,求所有人都回到房子所走的距离之和的最小值(距离为曼哈顿距离). 思路:比较明显的二分图最大权匹配模型,将每个人向房子连一条边,边权为曼哈顿距离的相反数(由于是求最小,所以先取反后求最大,最后再取反回来即可),然后用KM算法跑一遍然后取反就是答案.还可以用最小费用最大流做,方法是:从源点向每个人连一条边,容量为1,费用为0,从每个房子向汇点连一条边,容量为1,费用为0,从每个人向每个房子连一条边,容量为1,费用为曼哈顿距离的值,建好图后跑一遍

HDU 4862 Jump(更多的联合培训学校1)(最小费用最大流)

职务地址:pid=4862">HDU4862 最小费用流做的还是太少. 建图想不出来. . . 直接引用官方题解的话吧... 最小K路径覆盖的模型.用费用流或者KM算法解决,构造二部图,X部有N*M个节点.源点向X部每一个节点连一条边,流量1,费用0,Y部有N*M个节点,每一个节点向汇点连一条边.流量1,费用0.假设X部的节点x能够在一步之内到达Y部的节点y,那么就连边x->y,费用为从x格子到y格子的花费能量减去得到的能量.流量1,再在X部添加一个新的节点,表示能够从随意节点出发K

HDU 4862 Jump(多校联合训练1)(最小费用最大流)

题目地址:HDU4862 最小费用流做的还是太少.建图想不出来... 直接引用官方题解的话吧... 最小K路径覆盖的模型,用费用流或者KM算法解决,构造二部图,X部有N*M个节点,源点向X部每个节点连一条边,流量1,费用0,Y部有N*M个节点,每个节点向汇点连一条边,流量1,费用0,如果X部的节点x可以在一步之内到达Y部的节点y,那么就连边x->y,费用为从x格子到y格子的花费能量减去得到的能量,流量1,再在X部增加一个新的节点,表示可以从任意节点出发K次,源点向其连边,费用0,流量K,这个点向