训练指南 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 ...
随机推荐
- 【转】The test form is only available for requests from the local machine 解决方法
描述:在内网可以访问 WebServer ,在外部网站无法通过IP调用 webserver 转自:http://www.cnblogs.com/xiaogelove/p/3447283.htm ...
- Java操作Redis存储对象类型数据
背景描述 关于JAVA去操作Redis时,如何存储一个对象的数据,大家是非常关心的问题,虽然官方提供了存储String,List,Set等等类型,但并不满足我们现在实际应用.存储一个对象是是 ...
- SQL SERVER:删除筛选记录中前100条数据
delete from table1 where id in (select top 100 id from table1)
- eclipse关闭错误警告提示
- TOM的show_space
show_space查看对像数据块的空闲情况 CREATE OR REPLACE PROCEDURE show_space(p_segname IN VARCHAR2, p_owner IN VARC ...
- vue-transition-fade
<!Doctype> <html> <head> <meta charset="utf-8"> <meta name=&quo ...
- MAVEN 编译打包测试 指定本地jar
转载自:http://penuel.iteye.com/blog/1766102 maven对于互联网开发,进行版本管理有着不可或缺的作用; 而经常开发的程序猿直接联调或者依赖未上线或deploy的 ...
- 【Android开发日记】之入门篇(四)——Android四大组件之Activity
在Android中,无论是开发者还是用户,接触最多的就算是Activity.它是Android中最复杂.最核心的组件.Activity组件是负责与用户进行交互的组件,它的设计理念在很多方面都和Web页 ...
- Struts2 内建的验证规则
Struts2 内建的验证规则 conversion validator:转换验证器 date validator:日期验证器 double validator:浮点验证器 email validat ...
- Nginx配置配置文件详解
文章目录 配置文件 nginx.conf配置文件详解 用于调试.定位问题的配置参数 正常运行必备的配置参数 优化性能的配置参数 事件相关配置 Fastcgi相关配置参数 常需要调整的参数 nginx作 ...