题意

给出一些蚂蚁的点,给出一些树的点,两两对应,使他们的连线不相交,输出一种方案。

思路

一开始没想到怎么用最小权匹配……后来发现是因为最小权匹配的方案一定不相交(三角形两边之和大于第三边)……还是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 (最小权匹配)的更多相关文章

  1. Poj(3686),最小权匹配,多重匹配,KM

    题目链接 The Windy's | Time Limit: 5000MS | Memory Limit: 65536K | | Total Submissions: 4939 | Accepted: ...

  2. POJ 3565 Ants 【最小权值匹配应用】

    传送门:http://poj.org/problem?id=3565 Ants Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: ...

  3. poj 2516(拆点+最小权匹配)

    题目链接:http://poj.org/problem?id=2516 思路:考虑某种货物,由于某个订货商可能接受来自不同地区的货物,而某一地区的货物也可能送给不同的订货商,显然不能直接进行匹配,必须 ...

  4. poj 3686(拆点+最小权匹配)

    题目链接:http://poj.org/problem?id=3686 思路:显然工件为X集,机器为Y集合.由于每个机器一次只能加工一个部件,因此我们可以将一台机器拆成N个点,至于部件与机器之间连多大 ...

  5. poj 2195(KM求最小权匹配)

    题目链接:http://poj.org/problem?id=2195 思路:我们都知道KM使用来求最大权匹配的,但如果要求最小权匹配,只需把图中的权值改为负值,求一次KM,然后权值和取反即可. ht ...

  6. 【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)

    [POJ 2400] Supervisor, Supervisee(KM求最小权匹配) Supervisor, Supervisee Time Limit: 1000MS   Memory Limit ...

  7. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  8. POJ 2400 最小权匹配

    吐槽:首先,这道题的输入居然是错的.要将上下两个矩阵的位置换一下才可以出样例,也就是上面那个矩阵是employee对Supervisor的打分,下面那个矩阵才是Supervisor对employee的 ...

  9. HDU(1853),最小权匹配,KM

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Other ...

随机推荐

  1. Web App中的Flexbox应用

    虽然语法可能比较混杂,但 Flexbox 还是名不虚传的.它创造的是可伸缩的.有弹性的.可改变视觉顺序的智能盒子.它提供了简单的CSS布局方案范例让容器总是处于垂直水平居中的位置.使用盒模型来工作是非 ...

  2. Ado.Net要知道的东西

    什么是ADO.NET? ADO.NET就是一组类库,这组类库可以让我们通过程序的方式访问数据库,就像System.IO下的类用类操作文件一样,System.Data.这组类是用来操作数据库(不光是MS ...

  3. eclipse加速

    eclipse老是building workspace及自动更新问题,eclipse加速 最近用Eclipse开发oPhone的一个项目,每次打开Eclipse的时候,总是在build workspa ...

  4. [你必须知道的.NET]第三十二回,,深入.NET 4.0之,Tuple一二

    发布日期:2009.06.01 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. Tuple,是函数式编程的概念之一,早见于Elang.F#等动态 ...

  5. Good Bye 2014 D. New Year Santa Network 图论+期望

    D. New Year Santa Network   New Year is coming in Tree World! In this world, as the name implies, th ...

  6. Java多线程-线程的调度(休眠)

    Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提高程序的执行效率. 这里要明确的一点,不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制. ...

  7. TableViewCell自定义分割线

    产品设计的要求cell的分割线长度不用是整个屏幕宽,并且设计要求分割线为2px(两条),上下不同色. 实现如下: UITableView中将分割线样式改为None tableView.separato ...

  8. CentOS服务器的基本配置和查看

    一.设置静态IP 1.修改网卡配置 编辑:vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 #描述网卡对应的设备别名,例如ifcfg-e ...

  9. Data Flow ->> Term Extraction

    中文意思是关键词抽取,用于计算在文本中哪些词汇或者词组出现的频率最高.其实算法有两张:1)Frequency 2)TFIDF TFIDF的全称是Term Frequency and Inverse D ...

  10. matlab 扩大虚拟内存

    今天服务器挂了..用了自己电脑结果爆内存,分享一个扩大虚拟内存的方法,经测试有效.. 使用Matlab生成很大的图片时,碰到了"out of memory"的错误,导致图片无法生成 ...