训练指南 UVALive - 4043(二分图匹配 + KM算法)
layout: post
title: 训练指南 UVALive - 4043(二分图匹配 + KM算法)
author: "luowentaoaa"
catalog: true
mathjax: true
tags:
- 二分图匹配
- 图论
- 训练指南
Ants
题意
给你n个白点和n个黑点的平面坐标,要求用n条不相交的线连起来,每条线段连一个白点和黑点,每个点连一条线,也就是匹配。让你输出第i个白点所对应的黑点。
思路
二分图完美匹配问题。但是题目中有个线段不相交,怎么办?其实这个最佳完美匹配就是答案了。最佳完美匹配是权值和最大,那么我们就把两两点线段的权值搞成他们距离的负数即可。这样就不可能有相交的了。为什么?因为假设有相交,a1-b2,a2-b1,而dist(a1,b1)+dist(a2,b2) 肯定比前面交叉的小,画个四边形就很清楚了,那么负数就是大了,也就是说交叉的在我们设计的负权那里是小的,所以就是最佳,也就是不可能有交叉的。
这样分析清楚了之后,就只要直接套用KM就OK了!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353;
const int maxn=1e2+50;
const double inf=999999999999999.;
const double eps=1e-5;
struct node{
double x,y;
}white[150],black[150];
double g[150][150];
int nx,ny;
bool visx[maxn],visy[maxn];
double slack[maxn];
int linker[maxn];
double lx[maxn],ly[maxn];
bool dfs(int x){
visx[x]=true;
for(int y=0;y<ny;y++){
if(visy[y])continue;
double tmp=lx[x]+ly[y]-g[x][y];
if(fabs(tmp)<eps){
visy[y]=true;
if(linker[y]==-1||dfs(linker[y])){
linker[y]=x;return true;
}
}
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;
double 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;
}
double dis(node a,node b){
return double(sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)));
}
int n;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
int first=0;
while(cin>>n){
nx=ny=n;
if(first)cout<<endl;
first=1;
for(int i=0;i<n;i++){
cin>>white[i].x>>white[i].y;
}
for(int i=0;i<n;i++){
cin>>black[i].x>>black[i].y;
}
for(int i=0;i<n;i++)for(int j=0;j<n;j++)g[i][j]=-dis(black[i],white[j]);
KM();
for(int i=0;i<n;i++)cout<<linker[i]+1<<endl;
}
return 0;
}
训练指南 UVALive - 4043(二分图匹配 + KM算法)的更多相关文章
- 牛客多校第五场 E room 二分图匹配 KM算法模板
链接:https://www.nowcoder.com/acm/contest/143/E来源:牛客网 Nowcoder University has 4n students and n dormit ...
- 二分图匹配--KM算法
Kuhn-Munkres算法 KM算法,求完备匹配下的最大权匹配,时间复杂度O(\(n^3\)) 所谓的完备匹配就是在二部图中,x点集中的所有点都有对应的匹配 且 y点集中所有的点都有对应的匹配 ,则 ...
- 训练指南 UVALive - 3523 (双联通分量 + 二分图染色)
layout: post title: 训练指南 UVALive - 3523 (双联通分量 + 二分图染色) author: "luowentaoaa" catalog: tru ...
- 二分图最大权匹配——KM算法
前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...
- 训练指南 UVALive - 3126(DAG最小路径覆盖)
layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...
- 训练指南 UVALive - 3415(最大点独立集)
layout: post title: 训练指南 UVALive - 3415(最大点独立集) author: "luowentaoaa" catalog: true mathja ...
- 训练指南 UVALive - 3989(稳定婚姻问题)
ayout: post title: 训练指南 UVALive - 3989(稳定婚姻问题) author: "luowentaoaa" catalog: true mathjax ...
- 【HDU 2255】奔小康赚大钱 (最佳二分匹配KM算法)
奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)
layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...
随机推荐
- 周记【距gdoi:117天】
国庆被“吞”了 图论还剩下平面图.分层图.欧拉图…… 是现实太残酷还是自己兴趣不够? 努力吧.
- [COGS 2421] [HZOI 2016] 简单的Treap 笛卡尔树
笛卡尔树就是你给两维限制,一维堆R,一维二叉搜索树K,平地拔起一棵Treap,最广范的应用:用LCA求区间最值,建Treap,还有个什么范围top k我表示并不会查都查不到.它最妙最高的地方在于用栈来 ...
- 强大的JQuery数组封装使用
JQuery对数组的处理非常便捷并且功能强大齐全,一步到位的封装了很多原生js数组不能企及的功能.下面来看看JQuery数组的强大之处在哪. $.each(array, [callback]) 遍历 ...
- codeforces 1015C
C. Songs Compression time limit per test 1 second memory limit per test 256 megabytes input standard ...
- java的GC与内存泄漏
从诞生至今,20多年过去,Java至今仍是使用最为广泛的语言.这仰赖于Java提供的各种技术和特性,让开发人员能优雅的编写高效的程序.今天我们就来说说Java的一项基本但非常重要的技术内存管理 了解C ...
- hbase vs mongodb
1.HBase依赖于HDFS,HBase按照列族将数据存储在不同的hdfs文件中:MongoDB直接存储在本地磁盘中,MongoDB不分列,整个文档都存储在一个(或者说一组)文件中 (存储) 2.Mo ...
- There is an overlap in the region chain修复
ERROR: (region day_hotstatic,860010-2355010000_20140417_12_entry_00000000321,1400060700465.fda3b0aca ...
- The 'brew link' step did not complete successfully
在mac 上更新node时遇到了一系列的问题: 卸载node重新安装之后提示: The 'brew link' step did not complete successfully 其实这里已经给出了 ...
- 动态规划:LCIS
先给出状态转移方程: 定义状态 F[i][j]表示以a串的前i个整数与b串的前j个整数且以b[j]为结尾构成的LCIS的长度 状态转移方程: ①F[i][j] = F[i-][j] (a[i] != ...
- 谈谈openstack部署规模问题
理论上,单个openstack已设计成可水平扩展的系统,只要数据库足够快,消息总线足够多资源等,一个openstack系统可管理上千台物理服务器是没有问题的. 但是单个openstack规模大了之后, ...