https://www.nowcoder.com/acm/contest/201/L

题意:给你两条平行的直线和n个圆,在直线上面行走和在圆上和在圆内行走不需要耗费体力,除了这些区域外平面上经过任意两点需要走的距离都是欧几里得距离,求从直线1走到直线2所需要消耗的最小体力是多少。

题解:一开始以为是计算几何,但是冷静分析了一波后发现这个题要用最短路写,建边过程有点复杂:

1.从直线1到直线2要建边。

2.有n<1000个点,每个圆之间都应该有边,所以n方将所有圆连接起来,记得在圆内走和在圆上走不消耗体力需要处理一下。

3.从直线1到每个圆需要建边,从直线2到每个圆需要建边。

tips:最后建边的条数为2*(n*n+2*n+2)条,所以要把存边的数组开到1e6

建边完成后就简单的跑最短路就好,记得所有变量都要用double不容易出错

代码如下:

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define PI acos(-1)
#define eps 1e-8
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int maxn = 1e6+;
const int inf = 2.1e9;
const LL INF = ;
const int MOD = 1e9+;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=;while(b){if(b%)ans=ans*a%MOD;a=a*a%MOD;b/=;}return ans;}
double dpow(double a,LL b){double ans=1.0;while(b){if(b%)ans=ans*a;a=a*a;b/=;}return ans;}
int n;
struct point{
int x,y;
int r;
double d1,d2;
}p[maxn];
double Dis(point a,point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double dis1(int a,int b,int c1,int c2){
return abs(c1-c2)/sqrt(a*a+b*b);
}
double dis2(int a,int b,int c,int x,int y){
return abs(a*x+b*y+c)/sqrt(a*a+b*b);
}
struct node{
int v,nxt;
double w;
bool operator<(const node p)const{return p.w<w;}
}edge[maxn];
int head[maxn];
int tot;
void add(int u,int v,double w){
edge[tot].v=v;
edge[tot].w=w;
edge[tot].nxt=head[u];
head[u]=tot++;
}
double dis[maxn];
bool vis[maxn];
void dij(){
fill(dis+, dis + n+, inf);
dis[n+]=;
priority_queue<node>q;
node tmp;
tmp.v=n+;
tmp.w=;
q.push(tmp);
while(!q.empty()){
tmp=q.top();
q.pop();
if(!vis[tmp.v]){
vis[tmp.v]=;
int u=tmp.v;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].v;
if(dis[v]>dis[u]+edge[i].w){
dis[v]=dis[u]+edge[i].w;
tmp.w=dis[v];
tmp.v=v;
q.push(tmp);
}
}
}
}
}
int main(){
#ifndef ONLINE_JUDGE
FIN
#endif
int a,b,c1,c2;
cin>>n>>a>>b>>c1>>c2;
int ans=dis1(a,b,c1,c2);
// fuck(ans);
memset(head,-,sizeof(head));
tot=;
add(n+,n+,ans);
add(n+,n+,ans);
for(int i=;i<=n;i++){
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].r);
p[i].d1=max(0.0,dis2(a,b,c1,p[i].x,p[i].y)-p[i].r);
add(n+,i,p[i].d1);
add(i,n+,p[i].d1);
p[i].d2=max(0.0,dis2(a,b,c2,p[i].x,p[i].y)-p[i].r);
add(n+,i,p[i].d2);
add(i,n+,p[i].d2);
}
for(int i=;i<=n;i++){
for(int j=i+;j<=n;j++){
double d=Dis(p[i],p[j]);
d=max(0.0,d-p[i].r-p[j].r);
// fuck(d);
add(i,j,d);
add(j,i,d);
}
}
dij();
// for(int i=0;i<n+3;i++){
// printf("%10.6f\n",dis[i]);
// }
printf("%.6f\n",dis[n+]);
}

牛客 国庆七天乐 day1 L的更多相关文章

  1. 牛客国庆集训派对Day1 L New Game!(堆优化dijkstra+建图)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 初识python 文件读取 保存

    上一章最后一题的答案:infors.sort(key=lambda x:x['age'])print(infors)--->[{'name': 'laowang', 'age': 23}, {' ...

  2. C# FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址。"的错误

    FTP上传文件时出现"应 PASV 命令的请求,服务器返回了一个与 FTP 连接地址不同的地址."的错误 解决方法是在原代码上增加这句话 reqFTP.UsePassive = f ...

  3. Python3爬虫(四)请求库的使用requests

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.基本用法: 1. 安装: pip install requests 2. 例子: import request ...

  4. fastDFS 上传 java源码

    要想搭建fastDFS网上有相近的文章: 分布式文件系统 - FastDFS 在 CentOS 下配置安装部署 分布式文件系统 - FastDFS 配置 Nginx 模块及上传测试 首先下载fastd ...

  5. 关于 SSH Server 的整体设定

    # . 关于 SSH Server 的整体设定,包含使用的 port 啦,以及使用的密码演算方式 Port # SSH 预设使用 这个 port,您也可以使用多的 port ! # 亦即重复使用 po ...

  6. 从一个线上服务器警告谈谈backlog

    缘起 双十一如期而至,此时的我因为在处理客户的一个问题已经陷入了忙碌.突然,不断接到驻场实施发来的反馈,都是相同的反馈--"客户端操作缓慢". 我现在负责的服务器是一台接口服务器, ...

  7. spring 给静态变量注入值

    一般在spring中,给static变量加上@Autowired注解的时候会报空指针异常错误. 解决: 1.通过xml配置文件配置 这个就不多说了. 2.通过注解 @Component public ...

  8. 第一篇 Postman的初级使用之设置环境快速切换生成环境与测试环境

    POSTMAN是有谷歌的开源工具,在开发调试.测试执行过程中使用频率非常广泛,本文将记录一些postman在测试中常见的一些配置和使用方法 一.基本的页面区域 略,很简单,大家都会看,再有,学习下面的 ...

  9. 类和实例属性的查找顺序 mro查找

    如果多个类继承父类,然后又被多个类继承这种复杂的问题,可以使用 mro方法 例如: class A: pass class C(D): pass class B(D): pass class A(B, ...

  10. 3、shader深度测试(Cull、ZWrite 、ZTest )

    剔除和深度测试是渲染法线中的一个流程 Cull:默认情况下,Unity中给的所有Shader都是单面的,它都把反面的渲染给关闭掉了,如果你在开发的过程中需要使用到双面,只要把cull关闭(off)即可 ...