UVaLive 4043 Ants (最佳完美匹配)
题意:给定 n 个只蚂蚁和 n 棵树的坐标,问怎么匹配使得每个蚂蚁到树的连线不相交。
析:可以把蚂蚁和树分别看成是两类,那么就是一个完全匹配就好,但是要他们的连线不相交,那么就得考虑,最佳完美匹配是可以的,为什么呢,假设有两条线段a1-b1和a2-b2,那么如果相交,dist(a1, b1) + dist(a2, b2) > dist(a1, b2) + dist(a2, b1),自己画图看看就好,然后如果是最小的距离,那么就是可以的了,只要在用使得KM匹配时,把权值取反就好。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(i,x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 100 + 50;
const LL mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
} double w[maxn][maxn], x[maxn], y[maxn];
int prex[maxn], prey[maxn], son[maxn];
double slack[maxn];
int par[maxn]; void adjust(int v){
son[v] = prey[v];
if(prex[son[v]] != -2) adjust(prex[son[v]]);
} bool Find(int v){
FOR(i, 0, n) if(prey[i] == -1){
if(slack[i] > x[v] + y[i] - w[v][i]){
slack[i] = x[v] + y[i] - w[v][i];
par[i] = v;
}
if(x[v] + y[i] == w[v][i]){
prey[i] = v;
if(son[i] == -1){
adjust(i);
return true;
}
if(prex[son[i]] != -1) continue;
prex[son[i]] = i;
if(Find(son[i])) return true;
}
}
return false;
} int KM(){
ms(son, -1); ms(y, 0);
for(int i = 0; i < n; ++i){
x[i] = 0;
for(int j = 0; j < n; ++j)
x[i] = max(x[i], w[i][j]);
}
bool ok;
for(int i = 0; i < n; ++i){
for(int j = 0; j < n; ++j){
prex[j] = prey[j] = -1;
slack[j] = inf;
}
prex[i] = -2;
if(Find(i)) continue;
ok = false;
while(!ok){
double m = inf;
FOR(j, 0, n) if(prey[j] == -1) m = min(m, slack[j]);
for(int j = 0; j < n; ++j){
if(prex[j] != -1) x[j] -= m;
if(prey[j] != -1) y[j] += m;
else slack[j] -= m;
}
FOR(j, 0, n) if(prey[j] == -1 && slack[j] == 0.0){
prey[j] = par[j];
if(son[j] == -1){
adjust(j);
ok = true;
break;
}
prex[son[j]] = j;
if(Find(son[j])){
ok = true;
break;
}
}
}
}
} double a[maxn], b[maxn]; int main(){
while(scanf("%d", &n) == 1){
for(int i = 0; i < n; ++i) scanf("%lf %lf", a + i, b + i);
for(int i = 0; i < n; ++i){
double x, y;
scanf("%lf %lf", &x, &y);
for(int j = 0; j < n; ++j) w[i][j] = -sqrt(sqr(x-a[j]) + sqr(y-b[j]));
}
KM();
for(int i = 0; i < n; ++i)
printf("%d\n", son[i] + 1);
}
return 0;
}
UVaLive 4043 Ants (最佳完美匹配)的更多相关文章
- UVALive 4043 转化最佳完美匹配
首先黑点和白点是组成一个二分图这毫无疑问 关键是题目中要求的所有黑白配的线不能交叉...一开始我也没想到这个怎么转化为二分图里面的算法. 后来看书才知道,如果两两交叉,则可以把两根线当四边形的对角线, ...
- UVALive 4043 Ants(二分图完美匹配)
题意:每个蚁群有自己的食物源(苹果树),已知蚂蚁靠气味辨别行进方向,所以蚁群之间的行动轨迹不能重叠.现在给出坐标系中n个蚁群和n棵果树的坐标,两两配对,实现以上要求.输出的第 i 行表示第 i 个蚁群 ...
- Ants(二分图最佳完美匹配)
Ants Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 6904 Accepted: 2164 Special Ju ...
- UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)
UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- UVa 11383 少林决胜(二分图最佳完美匹配)
https://vjudge.net/problem/UVA-11383 题意: 给定一个N×N矩阵,每个格子里都有一个正整数W(i,j).你的任务是给每行确定一个整数row(i),每列也确定一个整数 ...
- 【LA4043 训练指南】蚂蚁 【二分图最佳完美匹配,费用流】
题意 给出n个白点和n个黑点的坐标,要求用n条不相交的线段把他们连接起来,其中每条线段恰好连接一个白点和一个黑点,每个点恰好连接一条线段. 分析 结点分黑白,很容易想到二分图.其中每个白点对应一个X结 ...
- UVA - 1045 The Great Wall Game(二分图最佳完美匹配)
题目大意:给出棋盘上的N个点的位置.如今问将这些点排成一行或者一列.或者对角线的最小移动步数(每一个点都仅仅能上下左右移动.一次移动一个) 解题思路:暴力+二分图最佳完美匹配 #include < ...
- Uva1349Optimal Bus Route Design(二分图最佳完美匹配)(最小值)
题意: 给定n个点的有向图问,问能不能找到若干个环,让所有点都在环中,且让权值最小,KM算法求最佳完美匹配,只不过是最小值,所以把边权变成负值,输出时将ans取负即可 这道题是在VJ上交的 #incl ...
- POJ 3565 Ants(最佳完美匹配)
Description Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on ...
随机推荐
- Javascript模块化编程require.js的用法
JS模块化工具requirejs教程(一):初识requirejs http://www.runoob.com/w3cnote/requirejs-tutorial-1.html JS模块化工具req ...
- SpringBoot2.0 url中出现特殊符号「带括号{}'"等等」时会抛出400错误
访问 http://127.0.0.1:8080/api?method=taxiong.goods.list¶ms={"page":1,"pageSize ...
- VS2017新建windows控制台程序打印中文乱码问题
最近刚换上VS2017,由于手头又要做个MFC的程序,所以写控制台程序做功能测试,然后发现居然乱码了. 于是用VS2017新建windows控制台应用程序,在main函数种加一句printf(&quo ...
- ubuntu安装了mysql 但是编译报错 mysql.h: No such file or directory
在Ubuntu体系中,已经安装了mysql,即应用sudo apt-get install mysql-server mysql-client 但是用C编译mysql数据库时,报错fatal erro ...
- 思科、华为、H3C命令对照表
思科 华为 H3C 描述 no undo undo 取消/关闭 当前设置 show display display 查看.显示 exit quit quit 退回上级 hostname sysname ...
- Linux系统编译Win32版本adb
源码版本:android 7.0 步骤1:source build/envsetup.sh 步骤2:lunch 步骤3:选择编译设备目标 步骤4:make adb USE_MINGW=y 下面是应对编 ...
- 83. Remove Duplicates from Sorted List + 82. Remove Duplicates from Sorted List II
▶ 删除单链表中的重复元素. ▶ 83. 把重复元素删得只剩一个,如 1 → 1 → 2 → 3 → 3 → 3 → 4 → 5 → 5 变成 1 → 2 → 3 → 4 → 5.注意要点:第一个元素 ...
- c#,读取二维码
/// <summary>/// 读取二维码/// 读取失败,返回空字符串/// </summary>/// <param name="filename&quo ...
- 跟我学算法- tensorflow 卷积神经网络训练验证码
使用captcha.image.Image 生成随机验证码,随机生成的验证码为0到9的数字,验证码有4位数字组成,这是一个自己生成验证码,自己不断训练的模型 使用三层卷积层,三层池化层,二层全连接层来 ...
- uvalive 7299 Boggle
Boggle is a game in which 16 dice with letters on each side are placed into a 4 × 4 grid. Players th ...