POJ 3565 Ants (最小权匹配)
题意
给出一些蚂蚁的点,给出一些树的点,两两对应,使他们的连线不相交,输出一种方案。
思路
一开始没想到怎么用最小权匹配……后来发现是因为最小权匹配的方案一定不相交(三角形两边之和大于第三边)……还是too young too simple……没有融会贯通……
代码
[cpp]
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#define MID(x,y) ((x+y)/2)
#define MEM(a,b) memset(a,b,sizeof(a))
#define REP(i, begin, m) for (int i = begin; i < begin+m; i ++)
using namespace std;
const int MAXV = 205; //X or Y点集大小
const int oo = 0x3fffffff;
const double eps = 1e-8;
template <class weight_type>
struct MaximalMatchingOfWeightedBipartiteGraph{
weight_type w[MAXV][MAXV]; //权值
int sv, tv; //Perfect Matching, sv should equal to tv
bool S[MAXV], T[MAXV];
weight_type lx[MAXV], ly[MAXV]; //X、Y点集可行顶标
int left[MAXV];
weight_type slack[MAXV];
void init(int v){
sv = tv = v;
MEM(w, 0);
}
void add_uedge(int u, int v, weight_type _w){
w[u][v] = _w;
}
bool cross_path(int u){
S[u] = true;
for (int v = 1; v <= tv; v ++){
if(T[v]) continue;
weight_type t = lx[u] + ly[v] - w[u][v];
if (t < eps){
T[v] = true;
if (left[v] == 0 || cross_path(left[v])){
left[v] = u;
return true;
}
}
else{
slack[v] = min(slack[v], t);
}
}
return false;
}
weight_type solve(){
//Init
MEM(left, 0);
for (int i = 1; i <= sv; i ++){
lx[i] = 0;
ly[i] = 0;
for (int j = 1; j <= tv; j ++)
lx[i] = max(lx[i], w[i][j]);
}
//Main
for (int i = 1; i <= sv; i ++){
for (int j = 1; j <= tv; j ++) slack[j] = oo;
while(1){
MEM(S, false); MEM(T, false);
if (cross_path(i)){
break;
}
else{
weight_type d = oo;
for (int j = 1; j <= tv; j ++)
if (!T[j]) d = min(d, slack[j]);
for (int j = 1; j <= sv; j ++)
if (S[j]) lx[j] -= d;
for (int j = 1; j <= tv; j ++){
if (T[j]) ly[j] += d;
else slack[j] -= d;
//匈牙利树中T集点ly不变,S集点lx减小,更新slack值
}
}
}
}
weight_type res = 0;
for(int i = 1; i <= sv; i ++) res += lx[i];
for(int i = 1; i <= tv; i ++) res += ly[i];
return res;
}
};
MaximalMatchingOfWeightedBipartiteGraph <double> km;
struct Point{
double x, y;
}p[MAXV];
double dist(int i, int j){
return sqrt((p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y));
}
int main(){
//freopen("test.in", "r", stdin);
//freopen("test.out", "w", stdout);
int n;
while(scanf("%d", &n) != EOF){
REP(i, 1, n){
scanf("%lf %lf", &p[i+n].x, &p[i+n].y);
}
REP(i, 1, n){
scanf("%lf %lf", &p[i].x, &p[i].y);
}
km.init(n);
REP(i, 1, n){
REP(j, 1, n){
km.add_uedge(i, j, -dist(i, j+n));
}
}
//printf("%f\n", -km.solve());
km.solve();
REP(i, 1, n){
printf("%d\n", km.left[i]);
}
}
return 0;
}
[/cpp]
POJ 3565 Ants (最小权匹配)的更多相关文章
- Poj(3686),最小权匹配,多重匹配,KM
题目链接 The Windy's | Time Limit: 5000MS | Memory Limit: 65536K | | Total Submissions: 4939 | Accepted: ...
- POJ 3565 Ants 【最小权值匹配应用】
传送门:http://poj.org/problem?id=3565 Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: ...
- poj 2516(拆点+最小权匹配)
题目链接:http://poj.org/problem?id=2516 思路:考虑某种货物,由于某个订货商可能接受来自不同地区的货物,而某一地区的货物也可能送给不同的订货商,显然不能直接进行匹配,必须 ...
- poj 3686(拆点+最小权匹配)
题目链接:http://poj.org/problem?id=3686 思路:显然工件为X集,机器为Y集合.由于每个机器一次只能加工一个部件,因此我们可以将一台机器拆成N个点,至于部件与机器之间连多大 ...
- poj 2195(KM求最小权匹配)
题目链接:http://poj.org/problem?id=2195 思路:我们都知道KM使用来求最大权匹配的,但如果要求最小权匹配,只需把图中的权值改为负值,求一次KM,然后权值和取反即可. ht ...
- 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)
[POJ 2400] Supervisor, Supervisee(KM求最小权匹配) Supervisor, Supervisee Time Limit: 1000MS Memory Limit ...
- 【POJ 2195】 Going Home(KM算法求最小权匹配)
[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
- POJ 2400 最小权匹配
吐槽:首先,这道题的输入居然是错的.要将上下两个矩阵的位置换一下才可以出样例,也就是上面那个矩阵是employee对Supervisor的打分,下面那个矩阵才是Supervisor对employee的 ...
- HDU(1853),最小权匹配,KM
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Other ...
随机推荐
- jQuery对象和javascript对象互换
jquery变js var obj=$("dom"); 或 var obj=jQuery("dom"); js 变 jquery var $jobj=$(obj ...
- Dungeon Game
The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...
- POJ 1411
#include<iostream> #include<stdio.h> #include<math.h> #define MAXN 50000 using nam ...
- 深入浅出ES6(八):Symbols
作者 Jason Orendorff github主页 https://github.com/jorendorff 你是否知道ES6中的Symbols是什么,它有什么作用呢?我相信你很可能不知道, ...
- WCF分布式开发步步为赢(8):使用数据集(DataSet)、数据表(DataTable)、集合(Collection)传递数据
数据集(DataSet).数据表(DataTable).集合(Collection)概念是.NET FrameWork里提供数据类型,在应用程序编程过程中会经常使用其来作为数据的载体,属于ADO.NE ...
- BZOJ 1191: [HNOI2006]超级英雄Hero 二分匹配
1191: [HNOI2006]超级英雄Hero Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或 ...
- nodejs的require模块及路径
在nodejs中,模块大概可以分为核心模块和文件模块. 核心模块是被编译成二进制代码,引用的时候只需require表示符即可,如(require('net')). 文件模块,则是指js文件.json文 ...
- 2016CVTE编程题:兔子藏洞
兔子藏洞 题目描述 一只兔子藏身于20个圆形排列的洞中(洞从1开始编号),一只狼从x号洞开始找,下次隔一个洞找(及在x+2号洞找),在下次个两个洞找(及在x+5号洞找),以此类推...它找了n次仍然没 ...
- lintcode:线段树的构造
线段树的构造 线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间.start和end都是整数,并按照如下的方式赋值: 根节点的 start 和 end 由 ...
- JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-004嵌套组件的注解AttributeOverrides
一.数据库 二.代码 1. package org.jpwh.model.advanced; import javax.persistence.AttributeOverride; import ja ...