UVA1349(带权二分图最大匹配 --> KM算法模板)
UVA1349
题意:给定一些有向带权边,求出把这些边构造成一个个环,总权值最小
解法:
对于带权的二分图的匹配问题可以用通过KM算法求解。
要求最大权匹配就是初始化g[i][j]为0,直接跑就可以;
要求最小权匹配就是初始化g[i][j]为-INF,加边的时候边权为负,最后输出答案的相反数。
因为要求每个点恰好属于一个圈,意味着每个点都有一个唯一的后继。 反过来,只要每个点都有唯一的后继,每个点一定属于某个圈。
唯一的是我们想到了二分图的概念,我们对于每个点,建立由u到v的二分图, 之后问题就转换成了二分图上的最小权完美匹配问题
#include<bits/stdc++.h>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define INF 0x3f3f3f3f
#define MAXN 100+10
using namespace std; struct KM {
int n;
int g[MAXN][MAXN];
int Lx[MAXN], Ly[MAXN];
int slack[MAXN];//记录距X匹配到Y点还需要多少权值
int match[MAXN];//记录每个X点匹配到的Y集中的点
bool S[MAXN], T[MAXN]; void init(int n) {
this->n = n;
for (int i = ; i < n; i++)
for (int j = ; j < n; j++)
g[i][j] = -INF;
//注意这里如果是求最大权值匹配和就赋值为0
//最小权值匹配和就是—INF
} void add_Edge(int u, int v, int val) {
g[u][v] = max(g[u][v], val);
} bool dfs(int i) {
S[i] = true;
for (int j = ; j < n; j++) {
if (T[j]) continue;
int tmp = Lx[i] + Ly[j] - g[i][j];
if (!tmp) {
T[j] = true;
if (match[j] == - || dfs(match[j])) {
match[j] = i;
return true;
}
}
else slack[j] = min(slack[j], tmp);
}
return false;
} void update() {
int a = INF;
for (int i = ; i < n; i++)
if (!T[i]) a = min(a, slack[i]);
for (int i = ; i < n; i++) {
if (S[i]) Lx[i] -= a;
if (T[i]) Ly[i] += a;
}
} void km() {
for (int i = ; i < n; i++) {
match[i] = -;
Lx[i] = -INF; Ly[i] = ;
for (int j = ; j < n; j++)
Lx[i] = max(Lx[i], g[i][j]);
}
for (int i = ; i < n; i++) {
for (int j = ; j < n; j++) slack[j] = INF;
while () {
for (int j = ; j < n; j++) S[j] = T[j] = false;
if (dfs(i)) break;
else update();
}
}
}
}Men; int main() {
int n;
while (scanf("%d", &n) == && n) {
Men.init(n);
REP(u, , n) {
int v;
while (scanf("%d", &v) && v) {
int w; scanf("%d", &w);
v--;
Men.add_Edge(u, v, -w);
}
} Men.km();
int ans = , flag = ;
REP(i, , n) {
if (Men.g[Men.match[i]][i] == -INF) {
//有未匹配到,就是不成功,因为题目要求的是完美匹配
flag = ;
break;
}
ans += Men.g[Men.match[i]][i];//累加权值
}
if (!flag) printf("N\n");
else printf("%d\n", -ans);//最后是输出的是负数
}
return ;
}
UVA1349(带权二分图最大匹配 --> KM算法模板)的更多相关文章
- 带权二分图最大匹配KM算法
二分图的判定 如果一个图是连通的,可以用如下的染色法判定是否二分图: 我们把X部的结点颜色设为0,Y部的颜色设为1. 从某个未染色的结点u开始,做BFS或者DFS .把u染为0,枚举u的儿子v.如果v ...
- HDU 2255 奔小康赚大钱(带权二分图最大匹配)
HDU 2255 奔小康赚大钱(带权二分图最大匹配) Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊 ...
- Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配)
Luogu 1559 运动员最佳匹配问题(带权二分图最大匹配) Description 羽毛球队有男女运动员各n人.给定2 个n×n矩阵P和Q.P[i][j]是男运动员i和女运动员j配对组成混合双打的 ...
- SPOJ 4206 Fast Maximum Matching (二分图最大匹配 Hopcroft-Carp 算法 模板)
题目大意: 有n1头公牛和n2头母牛,给出公母之间的m对配对关系,求最大匹配数.数据范围: 1 <= n1, n2 <= 50000, m <= 150000 算法讨论: 第一反应 ...
- "《算法导论》之‘图’":不带权二分图最大匹配(匈牙利算法)
博文“二分图的最大匹配.完美匹配和匈牙利算法”对二分图相关的几个概念讲的特别形象,特别容易理解.本文介绍部分主要摘自此博文. 还有其他可参考博文: 趣写算法系列之--匈牙利算法 用于二分图匹配的匈牙利 ...
- HDU 1045 - Fire Net - [DFS][二分图最大匹配][匈牙利算法模板][最大流求二分图最大匹配]
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1045 Time Limit: 2000/1000 MS (Java/Others) Mem ...
- 牛客多校第五场 E room 二分图匹配 KM算法模板
链接:https://www.nowcoder.com/acm/contest/143/E来源:牛客网 Nowcoder University has 4n students and n dormit ...
- 51Nod 飞行员配对(二分图最大匹配)(匈牙利算法模板题)
第二次世界大战时期,英国皇家空军从沦陷国征募了大量外籍飞行员.由皇家空军派出的每一架飞机都需要配备在航行技能和语言上能互相配合的2名飞行员,其中1名是英国飞行员,另1名是外籍飞行员.在众多的飞行员中, ...
- 二分图最大匹配 Hopcroft-Karp算法模板
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> ...
随机推荐
- 在4K屏下以超过VMWare默认的最高分辨率运行Linux系统
前言 4K 屏,有其优点也有其弊端.优点就是分辨率高,字体和图标看起来如丝一般顺滑:缺点就是字体和图标小,费眼睛.解决这个缺点的方法也很简单粗暴,就是将系统的显示比例放大.在高分屏不很普及的时候,无论 ...
- CSS3 animation属性中的steps实现GIF动图(逐帧动画)
相信 animation 大家都用过很多,知道是 CSS3做动画用的.而我自己就只会在 X/Y轴 上做位移旋转,使用 animation-timing-function 规定动画的速度曲线,常用到的 ...
- 搭建django项目连接mysql数据库环境
开通博客园这么久,即将写下第一篇博客,十分兴奋.首先了,庆祝自己写下了码农生涯博客园第一篇博客,其次了,庆祝自己经过了10个小时奋战,终于成功搭建django项目连接mysql数据库的环境.在此过程中 ...
- tensorflow feed_dict()
import tensorflow as tf a=tf.Variable(100) b=tf.Variable(200) c=tf.Variable(300) update1=tf.assign(c ...
- 根据navigator.userAgent返回值识别 浏览器
function validBrowser(){ var u_agent = navigator.userAgent; var browser_name='Failed to identify the ...
- ASP.NET Core 2.2 WebApi 系列【九】使用SignalR (作者:tenghao510 ) 学习及内容补充
原文地址: ASP.NET Core 2.2 WebApi 系列[九]使用SignalR 今天,看到了大牛的这篇博文, 发了一下评论, 我很惊喜, 没想到他很快就回复了我, 而且通过QQ帮助了S ...
- 关于JAVA中源码级注解的编写及使用
一.注解简介: 1.1.什么是"注解": 在我们编写代码时,一定看到过这样的代码: class Student { private String name; @Override ...
- c++ 中全局/静态存储区的内存污染问题
今天研究用回溯法解决八皇后问题,碰到了一个有趣的小问题. 看这篇随笔前,最好先看看我上一篇所写的 c++ 内存分配中一个有趣的小问题. 先看代码 #pragma once #pragma execut ...
- Java范型学习笔记
对于范型的使用或者说印象只有集合,其他地方即使使用过也不知道,反正就是只停留在List<E> Map<K, V>,最近刚好闲来无事,就找找资料学习一下:下列为个人学习总结,欢迎 ...
- 《自拍教程16》cmd的常用技巧
cmd.exe是Windows 自带的命令行操作交互界面软件. 虽然功能有限,但是毕竟是默认的命令行操作交互界面软件. 肯定所有的电脑都是自带的. 当然现在已经有很多改良版的,交互体验更好的cmd类似 ...