当前位置:网站首页>二分图最大权匹配(搭个板子,粘俩题)
二分图最大权匹配(搭个板子,粘俩题)
2022-06-21 19:39:00 【fighting_yifeng】
先讲二分图最大权匹配做了什么:
先说一说人尽皆知csl匈牙利最大匹配做的事是二分图两边点的最大匹配,但如果边权有值咋整呢,这就用到了二分图最大权匹配,让你可以匹配过后获得最大的权值。
沾板子(kuangbin好菜牛逼)
int g[maxn][maxn], linker[maxn], lx[maxn], ly[maxn];
int slack[maxn], nx, ny, t, n, m;
bool visx[maxn], visy[maxn];
bool dfs(int x)
{
visx[x] = 1;
for(int y = 0; y < ny; y++){
if(visy[y]) continue;
int tmp = lx[x] + ly[y] - g[x][y];
if(tmp == 0){
visy[y] = 1;
if(linker[y] == -1 || dfs(linker[y])){
linker[y] = x;
return 1;
}
}
else if(slack[y] > tmp) slack[y] = tmp;
}
return false;
}
int KM()
{
memset(linker, -1, sizeof(linker));
memset(ly, 0, sizeof(ly));
for(int i = 0; i < nx; i++)
{
lx[i] = -INF;
for(int j = 0; j < ny; j++)
if(g[i][j] > lx[i]) lx[i] = g[i][j];
}
for(int x = 0; x < nx; x++){
for(int i = 0; i < ny; i++)
slack[i] = INF;
while(true)
{
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
if(dfs(x)) break;
int d = INF;
for(int i = 0; i < ny; i++)
if(!visy[i] && d > slack[i])
d = slack[i];
for(int i = 0; i < nx; i++)
if(visx[i]) lx[i] -= d;
for(int i = 0; i < ny; i++)
if(visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
int res = 0;
for(int i = 0; i < ny; i++)
if(linker[i] != -1)
res += g[linker[i]][i];
return res;
}
粘俩题:
A.最大权匹配
P - 奔小康赚大钱 HDU - 2255
题意:卖房子,每套房子每个人给不同的钱,全卖出去赚最多的钱。
#include <iostream>
#include <cstdio>
#include <stack>
#include <cmath>
#include <set>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f;
const int maxn = 510;
int g[maxn][maxn], linker[maxn], lx[maxn], ly[maxn];
int slack[maxn], nx, ny;
bool visx[maxn], visy[maxn];
bool dfs(int x)
{
visx[x] = 1;
for(int y = 0; y < ny; y++){
if(visy[y]) continue;
int tmp = lx[x] + ly[y] - g[x][y];
if(tmp == 0){
visy[y] = 1;
if(linker[y] == -1 || dfs(linker[y])){
linker[y] = x;
return 1;
}
}
else if(slack[y] > tmp) slack[y] = tmp;
}
return false;
}
int KM()
{
memset(linker, -1, sizeof(linker));
memset(ly, 0, sizeof(ly));
for(int i = 0; i < nx; i++)
{
lx[i] = -INF;
for(int j = 0; j < ny; j++)
if(g[i][j] > lx[i]) lx[i] = g[i][j];
}
for(int x = 0; x < nx; x++){
for(int i = 0; i < ny; i++)
slack[i] = INF;
while(true)
{
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
if(dfs(x)) break;
int d = INF;
for(int i = 0; i < ny; i++)
if(!visy[i] && d > slack[i])
d = slack[i];
for(int i = 0; i < nx; i++)
if(visx[i]) lx[i] -= d;
for(int i = 0; i < ny; i++)
if(visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
int res = 0;
for(int i = 0; i < ny; i++)
if(linker[i] != -1)
res += g[linker[i]][i];
return res;
}
int main()
{
int n;
while(~scanf("%d", &n))
{
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
scanf("%d", &g[i][j]);
nx = ny = n;
printf("%d\n", KM());
}
return 0;
}
B最小权最大匹配
Q - Tour HDU - 3488
题意:n条道路经过n个城市回到原点,然后问最小行程距离。
#include <iostream>
#include <cstdio>
#include <stack>
#include <cmath>
#include <set>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f;
const int maxn = 510;
int g[maxn][maxn], linker[maxn], lx[maxn], ly[maxn];
int slack[maxn], nx, ny, t, n, m;
bool visx[maxn], visy[maxn];
bool dfs(int x)
{
visx[x] = 1;
for(int y = 0; y < ny; y++){
if(visy[y]) continue;
int tmp = lx[x] + ly[y] - g[x][y];
if(tmp == 0){
visy[y] = 1;
if(linker[y] == -1 || dfs(linker[y])){
linker[y] = x;
return 1;
}
}
else if(slack[y] > tmp) slack[y] = tmp;
}
return false;
}
int KM()
{
memset(linker, -1, sizeof(linker));
memset(ly, 0, sizeof(ly));
for(int i = 0; i < nx; i++)
{
lx[i] = -INF;
for(int j = 0; j < ny; j++)
if(g[i][j] > lx[i]) lx[i] = g[i][j];
}
for(int x = 0; x < nx; x++){
for(int i = 0; i < ny; i++)
slack[i] = INF;
while(true)
{
memset(visx, false, sizeof(visx));
memset(visy, false, sizeof(visy));
if(dfs(x)) break;
int d = INF;
for(int i = 0; i < ny; i++)
if(!visy[i] && d > slack[i])
d = slack[i];
for(int i = 0; i < nx; i++)
if(visx[i]) lx[i] -= d;
for(int i = 0; i < ny; i++)
if(visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
int res = 0;
for(int i = 0; i < ny; i++)
if(linker[i] != -1)
res += g[linker[i]][i];
return res;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
scanf("%d%d", &n, &m);
for(int i = 0; i <= n; i++)
for(int j = 0; j <= n; j++)
g[i][j] = -INF;
for(int i = 0; i < m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(g[a - 1][b - 1]) g[a - 1][b - 1] = max(g[a - 1][b - 1], -c);
else g[a - 1][b - 1] = -c;
}
nx = ny = n;
printf("%d\n", -KM());
}
return 0;
}
边栏推荐
猜你喜欢

Extend the clean, fresh and dense bag, and put a "safety lock" on the ingredients

Citus 11 for Postgres 完全开源,可从任何节点查询(Citus 官方博客)
![[parallel and distributed computing] 10B_ MapReduce GFS Implementation](/img/f9/3ce3c129d08f4e291f87217aae8fe2.png)
[parallel and distributed computing] 10B_ MapReduce GFS Implementation

【小程序】通过request实现小程序与后台asp.net的数据json传输(Post协议 图文+代码)

集群一---LVS负载均衡集群NAT模式及LVS负载均衡实战部署

What can one line of code do?

11、 Beautify the interface

Adum1401arwz-rl adenault digital signal isolation module

Introduction to high performance intranet DNS system

Fanuc robot carries out all backup, image backup and specific operations of loading backup files (picture and text)
随机推荐
DEDECMS织梦后台系统加入自己的栏目菜单
2022年全国最新消防设施操作员(中级消防设施操作员)模拟题库及答案
JVM的类加载过程
Server body 17: simple understanding of memory mapping and shared memory
Unity analog flashlight light source detector, AI attack range detection area, object detection in visual cone, fan-shaped area detection, circular area detection, cone area detection
What is more advantageous than domestic spot silver?
AB打包有的Shader没有触发IPreprocessShaders的回调
Tencent global digital ecology Conference - high speed intelligent computing special session!
What can one line of code do?
PCA based face recognition system and face pose analysis
What noteworthy technologies of gold: the importance of fund management
Quels sont les conseils que les programmeurs débutants ne connaissent pas?
最详细整理STL之vector基础
获取OpenHarmony源码:从DevEco Marketplace获取(1)
MySQL数据库---存储引擎
有哪些新手程序员不知道的小技巧?
Cylinder function block (FB) of PLC function block series
【并行与分布式计算】10b_MapReduce GFS Implementation
Data path: three people walk, there must be my teacher!
String类型转换成List<Integer>