https://codeforces.com/contest/958/problem/E3

当没有三点共线时,任意一个这样的点集都是保证可以找到答案的,(考虑任意一种有相交的连线方案,一定可以将其中两条相交的连线改成不相交的,并使得连线的总长度变小;显然连线的总长度最小的方案一定存在,则这种方案一定没有连线相交)

因此可以有一个分治做法:先在当前点集中找出最左、最下的点,找出一个点与其配对,使得以这两点间连线所在的直线划分开点集后,两边各自都满足白点数等于黑点数;显然一定能找到这个与其配对的点

找的方法就是其他点以选出这个点为中心做极角排序,然后双指针

复杂度n^2*log

本来以为分治时可以随便找出一个点,但事实上这样不对的,举个例子:

(以A2为选出点,则找不到配对点)

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
namespace X
{
struct Point
{
int x,y;
Point(int x=,int y=):x(x),y(y){}
};
typedef Point Vec;
Vec operator+(const Vec& a,const Vec& b)
{
return Vec(a.x+b.x,a.y+b.y);
}
Vec operator-(const Vec& a,const Vec& b)
{
return Vec(a.x-b.x,a.y-b.y);
}
int dcmp(int x)
//正为1,负为-1,0为0
{
if(x==) return ;
return x<?-:;
}
bool operator==(const Vec& a,const Vec& b)
//判向量相等
{
return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
}
double cross(const Vec& a,const Vec& b)
//叉积
{
return a.x*b.y-a.y*b.x;
}
};
using namespace X;
Point p[];
int an[];
int d[],tmp[];
int n;
double ang[];
bool vis[];
bool c1(int a,int b)
{
return ang[a]<ang[b];
}
bool c2(int a,int b)
{
return p[a].x<p[b].x||(p[a].x==p[b].x&&p[a].y<p[b].y);
}
void solve(int l,int r)
{
if(r<l) return;
swap(*min_element(d+l,d+r+,c2),d[l]);
int i;
for(i=l+;i<=r;i++)
ang[d[i]]=atan2(p[d[i]].y-p[d[l]].y,p[d[i]].x-p[d[l]].x);
sort(d+l+,d+r+,c1);
int len=r-l,a[]={,},nl,nr;
for(nl=l+,nr=l;nl<=r;nl++)//包含(nl,nr]的点,nl自身与l相连
{
while(nr<nl||(nr-nl+<len&&cross(p[d[(nr-l)%len+l+]]-p[d[l]],p[d[nl]]-p[d[l]])<))
{
++nr;
a[d[(nr-l-)%len+l+]<=n]++;
}
a[d[nl]<=n]--;
if(int(d[nl]<=n)+(d[l]<=n)==&&a[]==a[]) break;
}
if(d[l]<=n) an[d[l]]=d[nl];
else an[d[nl]]=d[l];
for(i=l+;i<=r;i++)
vis[i]=;
vis[nl]=;
tmp[]=;
for(i=nl+;i<=nr;i++)
{
vis[(i-l-)%len+l+]=;
tmp[++tmp[]]=d[(i-l-)%len+l+];
}
int t1=l;
for(i=l+;i<=r;i++)
if(!vis[i])
{
d[++t1]=d[i];
}
int t2=t1;
for(i=;i<=tmp[];i++)
d[++t2]=tmp[i];
solve(l+,t1);solve(t1+,t2);
}
int main()
{
int i;
while(scanf("%d",&n)==)
{
for(i=;i<=*n;i++) scanf("%d%d",&p[i].x,&p[i].y);
for(i=;i<=*n;i++) d[i]=i;
solve(,*n);
for(i=;i<=n;i++) printf("%d\n",an[i]-n);
}
return ;
}

双倍经验:https://vjudge.net/problem/UVA-1411

Guard Duty (hard) Codeforces - 958E3 || uva 1411的更多相关文章

  1. Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化

    https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...

  2. 【UVA 1411】 Ants (KM)

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

  3. UVA 1411 - Ants(二分图完美匹配)

    UVA 1411 - Ants 题目链接 题意:给定一些黑点白点,要求一个黑点连接一个白点,而且全部线段都不相交 思路:二分图完美匹配,权值存负的欧几里得距离,这种话,相交肯定比不相交权值小,所以做一 ...

  4. uva 1411 Ants (权值和最小的完美匹配---KM算法)

    uva 1411 Ants Description Young naturalist Bill studies ants in school. His ants feed on plant-louse ...

  5. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  6. uva 1411 Ants

    题意: 一个平面上有n个黑色的点,n个白色的点,要求黑色的点与白色点之间一一配对,且线段之间不相交. 思路: 线段不相交并不好处理,想了很久想不出,所以看了蓝书的讲解. 一个很明显的结论是,不相交的线 ...

  7. 【uva 1411 Ants蚂蚁们】

    题目大意: ·给你一个n,表示输入n个白点和n个黑点(输入每一个点的坐标).现在需要将各个白点和各个黑点一一用线段连接起来,需要满足这些线段不能够相交. ·特色: 我们如何保证线段间不相交. ·分析: ...

  8. CF 958E2. Guard Duty (medium)

    这道题是昨天linkfqy dalao上课讲的一道题 当时他讲的时候就想到了一种玄学的搞法,然后不敢相信自己切掉了 没想到后来CHJ dalao也想到了这种算法,然后发现是对的 后来10min就切掉了 ...

  9. UVa 1411 Ants(分治)

    https://vjudge.net/problem/UVA-1411 题意:n只蚂蚁和n颗苹果树,一一配对并且不能交叉. 思路:这就是巨人与鬼的问题.用分治法就行了. #include<ios ...

随机推荐

  1. javase练习题

    偶然看到一份javase的练习题,mark一下,以后练习下 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个 ...

  2. springmvc junit测试

    import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.ann ...

  3. css父元素背景覆盖其子元素背景

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. 封装class类为jar包提供给其他项目使用

    一.完成class类的编写与测试工作 二.完善javadoc注释,生成自己的API 注释要按照标准要求进行 Project -- generate  javadoc

  5. 树堆(Treap)

    平衡树 简介: 平衡二叉树(Balanced Binary Tree)具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.平衡二叉树的常用实现方 ...

  6. PS基本操作

    1 安装 赢政天下2015大师版 安装失败, 删除一下文件夹再重新安装 2 工作界面 2.1 界面 菜单栏; 标题栏; 工具箱; 工具箱选项栏; 面板; 状态栏; 文档窗口; 选项卡 2.2 文档窗口 ...

  7. Linux-awk和shell编程初步

    1 awk 格式: awk -选项 '处理' 输入 awk -F : '{print $1}' file -F指定分隔符, 默认是空格 $1 分割后的第一部分 $0 获得所有部分 NF 表示以分隔符分 ...

  8. 并不对劲的BJOI2019

    一些感想 现实并非游戏,并不支持反复刷关 猎人和防御工事一起被老山龙摧毁了: 猎人惨死雨中,结云村永无放晴之日: 猎人被狂龙病毒侵蚀,天空山上黑蚀龙泛滥. 好像这才是怪物猎人系列的真实结局呢 day ...

  9. UOJ309 UNR #2 排兵布阵

    包含不小于$\sqrt n$列的只有不大于$\sqrt n$行,修改时这些行打标记,否则暴力更新,操作一列的时候暴力更新这些行.合并没啥影响直接搞就是了.更新需要访问位置,感觉必须用哈希表,并不是特别 ...

  10. groovy语言和grails框架

    Groovy 是一种动态语言,它在 JVM 上运行,并且与 Java 语言无缝集成. Groovy 可以大大减少 Java 代码的数量.在 Groovy 中,不再需要为字段编写 getter 和 se ...