option=com_onlinejudge&Itemid=8&page=show_problem&problem=2044">https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2044

大致题意:

平面上有n个白点和n个黑点,求一种完美匹配使他们间的连线不相交

思路:要注意到,若有两种匹配相交,总能够当成对角线补成四边形,然后选四边形的两个边作为匹配就不会相交,并且一定匹配后的距离和缩短了,简单的几何知识,显然最小权匹配不会出现相交情况

防止被卡精度用了龙龙

//	Accepted	C++11	0.079
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
#define rep(i,n) for ( int i=0; i<int(n); i++ )
using namespace std;
typedef long long ll;
#define X first
#define Y second
typedef pair<ll,ll> pii; template <class T>
inline bool RD(T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0;
while (c != '-' && (c<'0' || c>'9')) c = getchar();
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template <class T>
inline void PT(T x) {
if (x < 0) {
putchar('-'); x = -x;
}
if (x > 9) pt(x / 10);
putchar(x % 10 + '0');
} const int N = 100+10;
const ll inf = 1LL<<50;
pii poix[N],poiy[N];
int n;
ll mp[N][N]; ll dis(int x,int y){
ll a = poix[x].X-poiy[y].X, b = poix[x].Y-poiy[y].Y;
return (a*a+b*b);
} int link[N];
ll lx[N],ly[N]; //y中各点匹配状态,x,y中的点标号
ll sla[N];
bool visx[N],visy[N];
bool DFS(int x)
{
visx[x] = true;
REP(y,n){
if(visy[y])continue;
ll tmp = lx[x] + ly[y] - mp[x][y];
if(tmp == 0){
visy[y] = true;
if(link[y] == -1 || DFS(link[y])){
link[y] = x;
return true;
}
}
else if(sla[y] > tmp) sla[y] = tmp;
}
return false;
}
ll KM()
{
memset(link,-1,sizeof(link));
memset(ly,0,sizeof(ly));
REP(i,n){
lx[i] = -inf;
REP(j,n) lx[i] = max(lx[i],mp[i][j]);
}
REP(x,n){
REP(i,n) sla[i] = inf;
while(true)
{
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
if(DFS(x)) break;
ll d = inf;
REP(i,n) if(!visy[i]) d = min(d,sla[i]);
REP(i,n){
if(visx[i]) lx[i] -= d;
if(visy[i])ly[i] += d;
else sla[i] -= d;
}
}
}
ll res = 0;
REP(i,n) if(link[i] != -1) res += mp[link[i]][i];
return res;
} int main(){
bool flag = 0;
while(~scanf("%d",&n)){
if(flag) puts("");
flag = 1;
REP(i,n) RD(poix[i].X),RD(poix[i].Y);
REP(i,n) RD(poiy[i].X),RD(poiy[i].Y);
REP(x,n) REP(y,n) mp[y][x] = -sqrt(dis(x,y))*10000000;
KM();
REP(i,n) printf("%d\n",link[i]);
}
//Print a blank line between datasets.
}

LA4043 - Ants(二分图完备最佳匹配KM)的更多相关文章

  1. Uvalive 4043 Ants —— 二分图最大权匹配 KM算法

    题目链接:https://vjudge.net/problem/UVALive-4043 题意: 给出n个白点和n个黑点的坐标, 要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和黑 ...

  2. KM(Kuhn-Munkres)算法求带权二分图的最佳匹配

    KM(Kuhn-Munkres)算法求带权二分图的最佳匹配 相关概念 这个算法个人觉得一开始时有点难以理解它的一些概念,特别是新定义出来的,因为不知道是干嘛用的.但是,在了解了算法的执行过程和原理后, ...

  3. 二分图匹配之最佳匹配——KM算法

    今天也大致学了下KM算法,用于求二分图匹配的最佳匹配. 何为最佳?我们能用匈牙利算法对二分图进行最大匹配,但匹配的方式不唯一,如果我们假设每条边有权值,那么一定会存在一个最大权值的匹配情况,但对于KM ...

  4. hdu2255 奔小康赚大钱 二分图最佳匹配--KM算法

    传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住 ...

  5. Hdu2255 奔小康赚大钱(二分图最大权匹配KM算法)

    奔小康赚大钱 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好 ...

  6. 二分图最大权匹配——KM算法

    前言 这东西虽然我早就学过了,但是最近才发现我以前学的是假的,心中感慨万千(雾),故作此篇. 简介 带权二分图:每条边都有权值的二分图 最大权匹配:使所选边权和最大的匹配 KM算法,全称Kuhn-Mu ...

  7. HDU2255 奔小康赚大钱 —— 二分图最大权匹配 KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    ...

  8. ACM学习历程—POJ3565 Ants(最佳匹配KM算法)

    Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on apple trees ...

  9. 二分图最佳匹配KM算法 /// 牛客暑期第五场E

    题目大意: 给定n,有n间宿舍 每间4人 接下来n行 是第一年学校规定的宿舍安排 接下来n行 是第二年学生的宿舍安排意愿 求满足学生意愿的最少交换次数 input 2 1 2 3 4 5 6 7 8 ...

随机推荐

  1. Atrenta电话面试(C++研发工程师)

    1.代码量是多少,你负责哪一块,工作量占%几,改进了什么   2.c++ 和 c 的 区别   3.list 和 vector 的 适用条件   4.hash_map 和 map 的 区别 , 使用h ...

  2. Redis 数据类型分析 字符串 哈希 列表 集合 有序集合 优缺点 分析 注意事项 存储结构

    一.提高Redis使用性能秘诀 KEY尽量少的原则,能放在1个KEY的就放入1个KEY,KEY开销很大尽量减少与Redis发生的交互次数,能批量的就批量,能事务.管道的就事务.管道从业务架构分析确定使 ...

  3. Python 描述符(Descriptor) 附实例

    在 Python 众多原生特性中,描述符可能是最少被自定义的特性之一,但它在底层实现的方法和属性却无时不刻被使用着,它优雅的实现方式体现出 Python 简洁之美. 定义 一个描述符是一个有" ...

  4. 【Linux】网卡配置与绑定

    Redhat Linux的网络配置,基本上是通过修改几个配置文件来实现的. 虽然也可以用ifconfig来设置IP,用route来配置默认网关,用hostname来配置主机名,但是重启后会丢失. 相关 ...

  5. luogu2483 【模板】k短路([SDOI2010]魔法猪学院)

    模板题 #include <iostream> #include <cstring> #include <cstdio> #include <queue> ...

  6. PHP读取xlsx Excel 文件

    <?php require_once 'simplexlsx.class.php'; if ( $xlsx = SimpleXLSX::parse('pricelist.xlsx') ) { p ...

  7. Leetcode 392.判断子序列

    判断子序列 给定字符串 s 和 t ,判断 s 是否为 t 的子序列. 你可以认为 s 和 t 中仅包含英文小写字母.字符串 t 可能会很长(长度 ~= 500,000),而 s 是个短字符串(长度 ...

  8. 【软考5】解释型 or 编译型

    导读:在上篇博客中,我们了解到,目前的编码语言经过不断的发展,已经经历了机器语言--汇编语言--高级语言的过程.虽然我们的编码语言在不停的升级,但作为计算机来说,它始终是一个只能理解0和1构成的机器语 ...

  9. PHP中file_put_contents追加和换行的实现方法

    在PHP的一些应用中需要写日志或者记录一些信息,这样的话.可以使用fopen(),fwrite()以及 fclose()这些进行操作.也可以简单的使用file_get_contents()和file_ ...

  10. 【Luogu】P1144最短路计数(BFS)

    题目链接 此题使用BFS记录最短路的条数.思路如下:因为是无权无向图,所以只要被BFS到就是最短路径.因此可以记录该点的最短路和最短路的条数:如果点y还没被访问过,则记录dis[y],同时令ans[y ...