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 ...
随机推荐
- 【面试题】Round A China New Grad Test 2014总结
我也有够懒的,今天才跑来写总结,自觉面壁中… 上一篇是Practice Round,今天是Round A,五道题. 每次做完都想说,其实题不难..但在做的过程中总是会各种卡,只有自己一行一行实现了,才 ...
- POJ 1001 Exponentiation(JAVA,BigDecimal->String)
题目 计算实数a的n次方,具体输出格式看案例 import java.util.*; import java.math.*; public class Main { public static voi ...
- 获取及管理Android 手机运营商及状态
主要类 TelephonyManager: telephonyManager.getCellLocation();//获得服务区 telephonyManager.getCellId();//获得服务 ...
- 2014 ACM/ICPC Asia Regional Xi'an Online(HDU 5007 ~ HDU 5017)
题目链接 A题:(字符串查找,水题) 题意 :输入字符串,如果字符串中包含“ Apple”, “iPhone”, “iPod”, “iPad” 就输出 “MAI MAI MAI!”,如果出现 “Son ...
- Codeforces Round #336 (Div. 2) D. Zuma 区间dp
D. Zuma Genos recently installed the game Zuma on his phone. In Zuma there exists a line of n gems ...
- hdu 4618(最大回文子矩阵)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4618 昨天多校的一道题,说多了都是泪啊,为了一道图论题,磨了那么久,结果是别的题都没看,没办法,补呗. ...
- spring_150801_autowired_qualifier
新建java project工程,建src.conf.test源码文件夹,导入相关包,需要spring的相关jar包和common-logging相关jar包 接口Service: package c ...
- iis 重启 (三种方法)
iis 重启 (三种方法) WINDOWS提供WEB服务的IIS有时候会出现访问过大导致网站打不开,这时重启IIS是最好的选择. 方法/步骤 1 1.界面操作 打开“控制面板”->“管理工具”- ...
- win32空项目创建窗体
#include "stdafx.h" //窗口过程函数(系统自动调用,即回调函数)LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM ...
- HttpWebRequest模拟登陆,存储Cookie以便登录请求后使用
[一篮饭特稀原创,转载请注明出自http://www.cnblogs.com/wanghafan/p/3284481.html] PostLogin :登录,并保存Cookie 1 public st ...