直接来构造。

考虑扫描线。从左到右扫,考虑当前扫到了一个左端点,我们把这个左端点连到其他点上。

我们可以找到这个点下方离他最近的线段,并且记下每条线段上方在扫描线左侧且最靠右,与这条线段中间没有其他线段的点,然后直接把左端点连到这样的点上就行了。容易证明这样的连发一定是对的。

找线段的过程用一个\(\text{set}\)来维护,对于每条线段记一个最后出现的在这条线段。

对于一些不好分类讨论的特殊情况,我们可以在所有线段的最下方加上一条直线,然后因为可能有斜率不存在的线段,我们可以把所有点随机旋转一下。就做完了

#include <cstdio>
#include <iostream>
#include <cmath>
#include <set>
#include <algorithm>
#define LL long long
#define db long double
using namespace std;
inline int read() {
int res = 0, flag = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') flag = 1;
for(; isdigit(ch); ch = getchar()) res = (res << 1) + (res << 3) + (ch ^ 48);
if(flag) res = ~res + 1; return res;
}
const db t = 1007.0/1009.0, cost = cos(t), sint = sin(t);
const db inf = 1e10;
const int N = 1e5 + 10;
int n;
struct Point {
int id;
db x, y;int rx, ry;
inline void get() {x = rx * cost - ry * sint, y = ry * cost + rx * sint;}
inline void print() {printf("%d %d ",rx,ry);}
inline void print1() {printf("%Lf %Lf ",x,y);}
inline bool operator < (const Point y) const{return (x < y.x);}
}p[N << 1], q[N << 1];
db nx;
struct Segment {
int l, r; mutable int lst; db k, b;
inline void get() {k = (p[l].y - p[r].y) / (p[l].x - p[r].x), b = p[l].y - p[l].x * k;}
inline void print() {printf("seg %Lf %Lf\n",k,b);}
inline bool operator < (const Segment y) const{return nx * k + b < nx * y.k + y.b;}
};
set <Segment> S; set <Segment>::iterator it;
int main() {
n = read();
for(register int i = 1; i <= n + n; i += 2) {
p[i].rx = read(), p[i].ry = read(), p[i].get();
p[i + 1].rx = read(), p[i + 1].ry = read(), p[i + 1].get();
if(p[i + 1] < p[i]) swap(p[i], p[i + 1]); p[i].id = i, p[i + 1].id = i + 1;
q[i] = p[i], q[i + 1] = p[i + 1];
}
sort(q + 1, q + n + n + 1);
Segment tmp;
tmp.k = 0, tmp.b = -inf, tmp.lst = 0, S.insert(tmp);
for(register int i = 1, id; i <= n + n; ++i) {
nx = q[i].x, id = q[i].id;
if(id & 1) { // left
tmp.l = id, tmp.r = id + 1, tmp.lst = id, tmp.get();
it = S.insert(tmp).first; --it;
if(it->lst) p[it->lst].print(), p[id].print(), printf("\n");
it->lst = id;
}
else { // right
tmp.l = id - 1, tmp.r = id, tmp.lst = id, tmp.get();
it = S.find(tmp); --it;
it->lst = id, S.erase(tmp);
}
}
}

CEOI2020 道路(Roads) Solution的更多相关文章

  1. bzoj1621 / P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm

    P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm 基础dfs,按题意递归即可. #include<iostream> #include< ...

  2. [USACO08OPEN]农场周围的道路Roads Around The Farm BZOJ 1621 DFS

    Farmer John's cows have taken an interest in exploring the territory around the farm. Initially, all ...

  3. 洛谷 题解 P2296 【寻找道路】

    Problem P2296 [寻找道路] solution 首先声明,这题我用了spfa,而: 关于spfa:它死了. 杀手: NOI 2018−T1 出题人 感谢出题人,没有卡spfa 用时: 20 ...

  4. 【洛谷P2907】 【USACO08OPEN】农场周围的道路 水模拟分治

    P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm 题目描述 Farmer John's cows have taken an interest in ex ...

  5. [APIO2008]

    A.免费道路roads 题意:给定n个点m条边的图,边有黑白颜色,求是否有一个生成树满足恰好有K条黑边,并输出方案. 题解:先加白边,求出必须加的黑边,然后加黑边到K条,剩下的用白边填充. 顺便说说, ...

  6. BZOJ1922:[SDOI2010]大陆争霸(最短路)

    Description 在一个遥远的世界里有两个国家:位于大陆西端的杰森国和位于大陆东端的 克里斯国.两个国家的人民分别信仰两个对立的神:杰森国信仰象征黑暗和毁灭 的神曾·布拉泽,而克里斯国信仰象征光 ...

  7. BZOJ 1626: [Usaco2007 Dec]Building Roads 修建道路( MST )

    计算距离时平方爆了int结果就WA了一次...... ------------------------------------------------------------------------- ...

  8. [Usaco2007 Dec]Building Roads 修建道路[最小生成树]

    Description Farmer John最近得到了一些新的农场,他想新修一些道路使得他的所有农场可以经过原有的或是新修的道路互达(也就是说,从任一个农场都可以经过一些首尾相连道路到达剩下的所有农 ...

  9. P3008 [USACO11JAN]道路和飞机Roads and Planes

    P3008 [USACO11JAN]道路和飞机Roads and Planes Dijkstra+Tarjan 因为题目有特殊限制所以不用担心负权的问题 但是朴素的Dijkstra就算用堆优化,也显然 ...

随机推荐

  1. lamp平台构建

    目录 lamp平台构建 安装httpd 安装mysql 安装php 配置apache 启用代理模块 配置虚拟主机 启用代理模块 验证 lamp平台构建 环境说明: 系统平台 IP 需要安装的服务 ce ...

  2. Linux入门操作介绍

    Linux 是由unix衍生而来(小知识:mac也是使用unix核心),由全世界的程序员一起开发的开源系统.如今基于linux已经有了很多版本,我们后面使用的就是衍生版本之一的Ubuntu. Ubun ...

  3. react实战系列 —— react 的第一个组件

    react 的第一个组件 写了 react 有一个半月,现在又有半个月没写了,感觉对其仍旧比较陌生. 本文分两部分,首先聊一下 react 的相关概念,然后不使用任何语法糖(包括 jsx)或可能隐藏底 ...

  4. 用lambda表达式和std::function类模板改进泛型抽象工厂设计

  5. Word 段前分页是什么?怎么设置?

    描述 这两个标题在第一个标题的页中,且两个标题都没有独立分页.要让每一个标题独立分页,需要对标题的格式进行修改. 段前分页指的是标题与标题之间不在同一个页中,每一个标题都在独立的页中. 设置段前分页 ...

  6. Minio分布式集群部署——Swarm

    最近研究minio分布式集群部署,发现网上大部分都是单服务器部署,而minio官方在github上现在也只提供了k8s和docker-compose的方式,网上有关与swarm启动minio集群的文章 ...

  7. 记一次twikoo引发的站点重大事故

    今天我测试私人博客的时候发现twikoo评论发生了错误,显示评论失败:0,我怀疑是我设置的twikoo安全域名有问题,所以我看了整个lssues,找到了我的解决方法! 1.关于配置安全域名后评论消失的 ...

  8. 算法模板:dijkstra

    #include<iostream> #include<algorithm> #include<cstring> #include<string> #i ...

  9. java数组---稀疏数组与数组之间的相互转化

    public static void main(String[] args) { int[][]array1=new int[11][11]; array1[1][2]=1; array1[2][3] ...

  10. 实时降噪(Real-time Denoising):Spatio-Temporal Filtering

    目录 空间滤波(Spatial Filtering) 基于距离的高斯滤波 双边滤波(Bilateral filtering) 联合双边滤波(Joint Bilateral filtering)[201 ...