【KM算法 模板】HDU
来源:互联网 发布:曼隆学院 知乎 编辑:程序博客网 时间:2024/06/05 14:31
Problem Description
n代表房子的数量,n行,每行n个数代表i个村名对第j间房出的价格
要求每个村民有房子住,能获得最大的价格是多少
思路:
裸的KM算法,求给定一个带权的二分图,求权值最大的完备匹配。
lx[i]代表第i个村民可以支付最大的钱,但并不是每个村民都能把最大的钱用掉。
slack[]数组,如果每个村民想用尽可能多的钱(因为扔掉太可惜),slack[j]数组代表买j这个房子需要扔掉最少的钱。
#include<bits/stdc++.h>using namespace std;#define maxn 305#define inf 0x3f3f3f3fint W[maxn][maxn];int lx[maxn], ly[maxn];int lef[maxn], slack[maxn];bool S[maxn], T[maxn];int n;bool dfs(int u){ S[u] = 1;//标记左集合u走过 for(int j = 1; j <= n; j++) { if(T[j]) continue; if(lx[u] + ly[j] == W[u][j])//lx[u]和ly[j]满足定值W[u][j] { T[j] = 1;//标记右集合j走过 if(!lef[j] || dfs(lef[j])) { lef[j] = u; return 1; } } else slack[j] = min(slack[j], lx[u] + ly[j] - W[u][j]);//记录买j这个房子需要扔掉最少的钱 } return 0;}void KW(){ int i, j; //一开始ly[i] = 0, lx[i]代表第i个村民能支出的最大价格 //lef[i]代表第i个房子对应那个村名 for(i = 1; i <= n; i++)//初始化 { lef[i] = lx[i] = ly[i] = 0; for(j = 1; j <= n; j++) { lx[i] = max(lx[i], W[i][j]); } } for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) slack[j] = inf;//初始化 while(1) { for(j = 1; j <= n; j++) S[j] = T[j] = 0;//初始化 if(dfs(i)) break;//匹配成功 int a = inf; for(j = 1; j <= n; j++) { if(!T[j]) a = min(a, slack[j]);//求需要减少的最少价格 } if(a == inf) break; for(j = 1; j <= n; j++)//更新lx[],ly[],slack[] { if(S[j]) lx[j] -= a; if(T[j]) ly[j] += a; else slack[j] -= a; } } }}int main(){ int i, j; while(~scanf("%d", &n)) { for(i = 1; i <= n; i++) for(j = 1; j <= n; j++) scanf("%d", &W[i][j]); KW(); int ans = 0; for(i = 1; i <= n; i++) { ans += W[lef[i]][i]; } printf("%d\n", ans); } return 0;}
阅读全文
0 0
- 【KM算法 模板】HDU
- hdu 2255KM算法模板
- hdu 2255(KM算法模板)
- hdu 2255(KM算法模板)
- hdu-2255(KM算法模板)
- KM算法模板(HDU 2255)
- HDU 2255 KM算法—模板
- KM算法模板
- KM算法 详解+模板
- KM算法详解+模板
- KM算法 详解+模板
- KM算法 详解+模板
- KM算法模板
- KM算法模板
- KM算法 详解+模板
- KM算法 详解+模板
- KM算法 详解+模板
- KM算法模板
- 每日一练_08
- 设置centos7的网络连接
- 1039. 到底买不买(20)
- 窗口
- this
- 【KM算法 模板】HDU
- Split Linked List in Parts(LeetCode725)
- 编程求出1+2+3...+n的值
- contine语句
- C++多线程中调用python api函数 GIL的使用
- 多线程下载
- 多项式求和
- 1040. 有几个PAT(25)
- 国王将金币作为工资,发放给忠诚的骑士。