uva11383 转化为 二分图匹配
给定一个n*n矩阵,每个格子里都有一个正整数w(i,j)。你的任务是给每行确定一个整数row(i),没列也确定一个正整数col(i),使得对于任意格子(i,j),w(i,j) <= row(i)+col(j).所有row(i)和col(i)之和应最小
由w(i,j)<=row(i)+col(j) 使用km算法时在推导的时候有这样一个公式 Lx[i]+Ly[i]>=W[i][j], 且KM使得 Lx[i]+Ly[i]==W[i][j],那么可以转化为KM来计算。
每个row[i] 为Lx[i], 那么col[i]为Ly[i], w[i][j]为i和j连接的边的权重。
#include <algorithm>
#include <string.h>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
/* KM算法
* 复杂度O(nx*nx*ny)
* 求最大权匹配
* 若求最小权匹配,可将权值取相反数,结果取相反数
* 点的编号从0开始
*/
const int N = ;
const int INF = ;
int nx,ny; //两边的点数
int W[N][N]; //二分图描述
int Left[N],Lx[N],Ly[N]; //y中各点匹配状态 x,y中的点标号
int slack[N];
bool S[N],T[N];
vector<int> G[N];
bool DFS(int x) {
S[x] = true;
for(int y = ; y < ny; y++){
if(T[y]) continue;
int tmp = Lx[x] + Ly[y] - W[x][y];
if(tmp==){
T[y] = true;
if(Left[y] == - || DFS(Left[y])){
Left[y] = x;
return true;
}
}
else if(slack[y] > tmp)
slack[y] = tmp;
}
return false;
}
void KM(){
memset(Left, -, sizeof(Left));
memset(Ly,, sizeof(Ly));
for(int i = ;i < nx;i++){
Lx[i] = -INF;
for(int j = ;j < ny;j++)
Lx[i] = max(Lx[i],W[i][j]);
}
for(int x = ;x < nx;x++){
for(int i = ;i < ny;i++)
slack[i] = INF;
while(true){
memset(S, false, sizeof(S));
memset(T, false, sizeof(T));
if(DFS(x)) break;
int d = INF;
for(int i = ;i < ny;i++)
if(!T[i] && d > slack[i])
d = slack[i];
for(int i = ;i < nx;i++)
if(S[i])
Lx[i] -= d;
for(int i = ;i < ny;i++){
if(T[i])Ly[i] += d;
else slack[i] -= d;
}
}
}
}
//HDU 2255
double x1[N],x2[N],yy1[N],yy2[N];
int main()
{
int n;
while(scanf("%d",&n) == ){
for(int i =; i<n; i++){
for(int j =; j < n; ++j){
scanf("%d",&W[i][j]);
}
}
nx = ny = n;
KM();
int sum=;
for(int i=; i<n-; i++) { printf("%d ",Lx[i]); sum+=Lx[i];} printf("%d\n",Lx[n-]);
for(int i=; i<n-; i++) { printf("%d ",Ly[i]); sum+=Ly[i];}printf("%d\n",Ly[n-]);
printf("%d\n",sum+Lx[n-]+Ly[n-]);
}
return ;
}
uva11383 转化为 二分图匹配的更多相关文章
- BZOJ1059 [ZJOI2007]矩阵游戏 二分图匹配 匈牙利算法
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1059 题意概括 有一个n*n(n<=200)的01矩阵,问你是否可以通过交换整行和整列使得左 ...
- [Codeforces 1027 F] Session in BSU [并查集维护二分图匹配问题]
题面 传送门 思路 真是一道神奇的题目呢 题目本身可以转化为二分图匹配问题,要求右半部分选择的点的最大编号最小的一组完美匹配 注意到这里左边半部分有一个性质:每个点恰好连出两条边到右半部分 那么我们可 ...
- POJ 2536 Gopher II (ZOJ 2536) 二分图匹配
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1882 http://poj.org/problem?id=2536 题目大 ...
- UESTC-1963咸鱼咕咕咕(二分图匹配)
咸鱼咕咕咕 Time Limit: 1000 MS Memory Limit: 64 MB Submit Status 咸鱼有个咕咕笼. 咕咕笼可以划分成m×nm×n个格子,每个小格子可以放下 ...
- 【洛谷P1963】[NOI2009]变换序列(二分图匹配)
传送门 题意: 现有一个\(0\)到\(n-1\)的排列\(T\),定义距离\(D(x,y)=min\{|x-y|,N-|x-y|\}\). 现在给出\(D(i, T_i)\),输出字典序最小的符合条 ...
- HDU5090--Game with Pearls 二分图匹配 (匈牙利算法)
题意:给N个容器,每个容器里有一定数目的珍珠,现在Jerry开始在管子上面再放一些珍珠,放上的珍珠数必须是K的倍数,可以不放.最后将容器排序,如果可以做到第i个容器上面有i个珍珠,则Jerry胜出,反 ...
- UVa 二分图匹配 Examples
这些都是刘汝佳的算法训练指南上的例题,基本包括了常见的几种二分图匹配的算法. 二分图是这样一个图,顶点分成两个不相交的集合X , Y中,其中同一个集合中没有边,所有的边关联在两个集合中. 给定一个二分 ...
- 【ACM/ICPC2013】二分图匹配专题
前言:居然三天没有更新了..我的效率实在太低,每天都用各种各样的理由拖延,太差了!昨天的contest依旧不能让人满意,解出的三题都是队友A的,我又卖了一次萌..好吧废话不多说,今天我要纪录的是二分图 ...
- HDU4685:Prince and Princess(二分图匹配+tarjan)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
随机推荐
- 深入浅出WPF之Binding的使用(一)
在WPF中Binding可以比作数据的桥梁,桥梁的两端分别是Binding的源(Source)和目标(Target).一般情况下,Binding源是逻辑层对象,Binding目标是UI层的控件对象:这 ...
- C# 日志系统 log4net 配置及使用
1.引用Dll 版本是:1.2.10.0,下载Dll 2.Web.config文件配置 <?xml version="1.0" encoding="utf-8&qu ...
- nodejs事件的监听与事件的触发
nodejs事件(Events) 一.事件机制的实现 Node.js中大部分的模块,都继承自Event模块(http://nodejs.org/docs/latest/api/events.html ...
- 9.5Django
2018-9-5 15:23:00 配置数据库信息 setting MySQLdb 不支持python3 创建表 pycharm 连接数据库 好强大的赶脚
- Docker添加镜像加速器
Docker默认pull连接镜像为国外镜像,速度较慢,注册阿里云可以生成一个镜像加速器 登录阿里云 https://cr.console.aliyun.com获取私有加速地址 修改配置文件/etc/d ...
- 2018-2019-2 20165330《网络对抗技术》Exp3 免杀原理与实践
目录 基础问题 相关知识 实验内容 实验步骤 实验过程中遇到的问题 离实战还缺些什么技术或步骤? 实验总结与体会 实验内容 正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil- ...
- Gym - 101020H Weekend floyd+next_permutation
https://vjudge.net/problem/Gym-101020H 题意:正常读取方式给你一个图(双向的),然后给你f个点,让你找一条路从1到n的最短路,要求经过f个点(以任意顺序). 题解 ...
- python数据结构之树(二叉树的遍历)
树是数据结构中非常重要的一种,主要的用途是用来提高查找效率,对于要重复查找的情况效果更佳,如二叉排序树.FP-树. 本篇学习笔记来自:二叉树及其七种遍历方式.python遍历与非遍历方式实现二叉树 介 ...
- 停机问题(英语:halting problem)是逻辑数学中可计算性理论的一个问题。通俗地说,停机问题就是判断任意一个程序是否能在有限的时间之内结束运行的问题。该问题等价于如下的判定问题:是否存在一个程序P,对于任意输入的程序w,能够判断w会在有限时间内结束或者死循环。
htps://baike.baidu.com/item/停机问题/4131067?fr=aladdin 理发师悖论:村子里有个理发师,这个理发师有条原则是,对于村里所有人,当且仅当这个人不自己理发,理 ...
- C++三大特性之继承
原文地址:https://qunxinghu.github.io/2016/09/12/C++%20%E4%B8%89%E5%A4%A7%E7%89%B9%E6%80%A7%E4%B9%8B%E7%B ...