链接:https://ac.nowcoder.com/acm/contest/201/L
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 1048576K,其他语言2097152K
Special Judge, 64bit IO Format: %lld

题目描

Eagle Jump公司正在开发一款新的游戏。Hifumi Takimoto作为其中的员工,获得了提前试玩的机会。现在她正在试图通过一个迷宫。
这个迷宫有一些特点。为了方便描述,我们对这个迷宫建立平面直角坐标系。迷宫中有两条平行直线 L1:Ax+By+C1=0, L2:Ax+By+C2=0,还有 n 个圆 Ci:(x−xi)2+(y−yi)2=ri2Ci:(x−xi)2+(y−yi)2=ri2。角色在直线上、圆上、园内行走不消耗体力。在其他位置上由S点走到T点消耗的体力为S和T的欧几里得距离。
Hifumi Takimoto想从 L1 出发,走到 L2 。请计算最少需要多少体力。

输入描述:

第一行五个正整数 n,A,B,C1,C2(1≤ n ≤ 1000, -10000 ≤ A,B,C1,C2≤ 10000),其中 A,B 不同时为 0。
接下来 n 行每行三个整数 x,y,r(-10000 ≤ x,y ≤ 10000, 1≤ r ≤ 10000) 表示一个圆心为 (x,y),半径为 r 的圆。

输出描述:

仅一行一个实数表示答案。与正确结果的绝对误差或者相对误差不超过 10-4
即算正确。
示例1

输入

2 0 1 0 -4
0 1 1
1 3 1

输出

0.236068

题目大意:

给你两条平行的直线,n个圆,在直线和圆上运动不需要能量(距离),问从一条直线到另一条直线最少需要多少距离。

从一条直线到另一条直线,一共可能经过三种路径。

直线到直线,直线到圆,圆到圆,都是无向边。

这三种分别有1,2n,n^2条边,注意链式前向星开空间需要乘2。

以后最好还是用dijkstra的堆优化版本吧,spfa被卡了。

总结一下各种最短路算法的适用条件(V为点数,E为边数):

Floyd:V^3

Spfa:平均kE(一般k为小常数2,表示每个点平均进队次数) 最差VE 可见稠密图卡爆,故若正权图就用dijkstra吧,只有负权图用spfa

Dijkstra:普通V^2 堆优化ElogV 可见稠密图上普通版,其他只要都上堆优化版,不过只适用于正权图的情况

还涉及到一点计算几何。要入门计算几何了嘛?233

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
typedef long long ll;
const double eps=1e-;
const int mod=;
const double inf=;
const int maxn=;
const int maxm=; using namespace std; struct tcircle
{
double x,y,r;
};
tcircle cir[maxn+]; double dotdot(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
} double dotline(double x,double y,double a,double b,double c)
{
return fabs(a*x+b*y+c)/sqrt(a*a+b*b);
} double lineline(double a,double b,double c1,double c2)
{
return fabs(c1-c2)/sqrt(a*a+b*b);
} int to[(maxn+)*(maxn+)+];
double w[(maxn+)*(maxn+)+];
int nex[(maxn+)*(maxn+)+];
int head[maxn+],cnt=; void addedge(int u,int v,double wei)
{
to[cnt]=v;w[cnt]=wei;
nex[cnt]=head[u];head[u]=cnt++;
to[cnt]=u;w[cnt]=wei;
nex[cnt]=head[v];head[v]=cnt++;
} struct tnode
{
double d;
int u;
bool operator<(const tnode& rhs) const
{
return d>rhs.d;
}
};
double dis[maxn+];
int done[maxn+]; int main()
{
int n;
double a,b,c1,c2;
scanf("%d%lf%lf%lf%lf",&n,&a,&b,&c1,&c2);
for(int i=;i<=n;i++)
scanf("%lf%lf%lf",&cir[i].x,&cir[i].y,&cir[i].r); memset(head,-,sizeof(head));
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
{
double d=dotdot(cir[i].x,cir[i].y,cir[j].x,cir[j].y);
if(d>cir[i].r+cir[j].r)
addedge(i,j,d-cir[i].r-cir[j].r);
else
addedge(i,j,);
}
}
for(int i=;i<=n;i++)
{
double d;
d=dotline(cir[i].x,cir[i].y,a,b,c1);
if(d>cir[i].r)
addedge(i,n+,d-cir[i].r);
else
addedge(i,n+,);
d=dotline(cir[i].x,cir[i].y,a,b,c2);
if(d>cir[i].r)
addedge(i,n+,d-cir[i].r);
else
addedge(i,n+,);
}
addedge(n+,n+,lineline(a,b,c1,c2)); for(int i=;i<=n+;i++)
dis[i]=inf;
dis[n+]=;
memset(done,,sizeof(done));
priority_queue<tnode> q;
q.push((tnode){,n+});
while(!q.empty())
{
tnode x=q.top();q.pop();
int u=x.u;
if(done[u])
continue;
done[u]=;
for(int i=head[u];i!=-;i=nex[i])
{
int l=to[i];
if(dis[l]>dis[u]+w[i])
{
dis[l]=dis[u]+w[i];
q.push((tnode){dis[l],l});
}
}
} printf("%f\n",dis[n+]); return ;
}

牛客国庆集训派对Day1 L New Game!(堆优化dijkstra+建图)的更多相关文章

  1. 牛客国庆集训派对Day1 L-New Game!(最短路)

    链接:https://www.nowcoder.com/acm/contest/201/L 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1048576K,其他语言20 ...

  2. 2019牛客国庆集训派对day1(A, B E F K)

    链接:https://ac.nowcoder.com/acm/contest/1099#question A:可知符合条件的图中间肯定存在一个由1构成的矩形,找到由1构成矩形的边界,判断出现的1的数量 ...

  3. 牛客国庆集训派对Day1 Solution

    A    Tobaku Mokushiroku Kaiji 水. #include <bits/stdc++.h> using namespace std; ], b[]; void Ru ...

  4. 牛客国庆集训派对Day1:J:Princess Principal(栈模拟求括号匹配)

    题目描述 阿尔比恩王国(the Albion Kingdom)潜伏着一群代号“白鸽队(Team White Pigeon)”的间谍.在没有任务的时候,她们会进行各种各样的训练,比如快速判断一个文档有没 ...

  5. 2019牛客国庆集训派对day1 K题 双向链表练习题 splay区间翻转

    题目链接: 解法: 先建n颗平衡树,合并的时候将a中最右的结点翻转到根节点,b中最左的结点翻转到根节点,对合并后的根节点进行标记. #include <bits/stdc++.h> usi ...

  6. 牛客国庆集训派对Day1.B.Attack on Titan(思路 最短路Dijkstra)

    题目链接 \(Description\) 给定\(n,m,C\)及大小为\((n+1)(m+1)\)的矩阵\(c[i][j]\).平面上有\((n+1)(m+1)\)个点,从\((0,0)\)编号到\ ...

  7. 牛客国庆集训派对Day1 B. Attack on Titan

    B. Attack on Titan 链接 #include<cstdio> #include<algorithm> #include<cstring> #incl ...

  8. 2019牛客国庆集训派对day1

    C 存每个值存在的位置,枚举末尾的值,再枚举前面的值,哈希二分出最长相同的,即剩下的为不同的 D \(f_{i,j,k}\)为前i位,最后一个3因子在j,次因子在k G bitset处理有多少位置符合 ...

  9. 牛客国庆集训派对Day6 A Birthday 费用流

    牛客国庆集训派对Day6 A Birthday:https://www.nowcoder.com/acm/contest/206/A 题意: 恬恬的生日临近了.宇扬给她准备了一个蛋糕. 正如往常一样, ...

随机推荐

  1. GitHub远程库的搭建以及使用

    GitHub远程库的搭建 一).配置SSH 步骤: 1).注册GitHub账号 2).本地git仓库与远程的GitHub仓库的传输要通过SSH进行加密 3).创建SSH key ​ 1.检查在用户主目 ...

  2. ubuntu 16.04 上使用pybind11进行C++和Python代码相互调用 | Interfacing C++ and Python with pybind11 on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/a41adc1/,欢迎阅读! Interfacing C++ and Python with pybind11 on ubuntu ...

  3. Ubuntu 16.04上源码编译Poco并编写cmake文件 | guide to compile and install poco cpp library on ubuntu 16.04

    本文首发于个人博客https://kezunlin.me/post/281dd8cd/,欢迎阅读! guide to compile and install poco cpp library on u ...

  4. OutOfMemoryError本地线程不足问题分析

    java.lang.OutOfMemoryError本地线程不足问题 11月份中旬客户方的一个系统突然报内存异常,当时是早上上班的时候碰到该项目的项目经理,还跟该项目的项目经理开玩笑说你们系统上线将近 ...

  5. python+selenium +unittest生成HTML测试报告

    python+selenium+HTMLTestRunner+unittest生成HTML测试报告 首先要准备HTMLTestRunner文件,官网的HTMLTestRunner是python2语法写 ...

  6. linux 相关零碎知识整理

    1.启动bash shell 大部分linux系统启动用户命令行接口(cli)环境时使用默认的bash shell,在bash shell启动时,它将自动执行位于用户主目录下的.bashrc中的命令. ...

  7. 从零开始手写 spring ioc 框架,深入学习 spring 源码

    IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...

  8. spark graphX作图计算

    一.使用graph做好友推荐 import org.apache.spark.graphx.{Edge, Graph, VertexId} import org.apache.spark.rdd.RD ...

  9. Gitlab用户信息批量导出

    前言 因运维体系中涉及到用户权限管理及统计,需将Gitlab用户数据提取出来并录入到公司内部自建的权限统计平台. 本文将对Gitlab的用户信息数据批量导出进行操作说明! 思路 A)要对数据进行批量的 ...

  10. 深入浅出Spring(三)

    我为大家简单介绍了一下Spring框架核心内容中的IoC,接下来我们继续讲解另一个核心AOP(Aspect Oriented Programming),即面向切面编程. 1.OOP回顾 在介绍AOP之 ...