博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
牛客 国庆七天乐 day1 L
阅读量:4583 次
发布时间:2019-06-09

本文共 2406 字,大约阅读时间需要 8 分钟。

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 #include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PI acos(-1)#define eps 1e-8#define fuck(x) cout<<#x<<" = "<
<
PII;const int maxn = 1e6+5;const int inf = 2.1e9;const LL INF = 999999999999999;const int MOD = 1e9+7;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=1;while(b){ if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}double dpow(double a,LL b){ double ans=1.0;while(b){ if(b%2)ans=ans*a;a=a*a;b/=2;}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
q; node tmp; tmp.v=n+1; tmp.w=0; q.push(tmp); while(!q.empty()){ tmp=q.top(); q.pop(); if(!vis[tmp.v]){ vis[tmp.v]=1; int u=tmp.v; for(int i=head[u];i!=-1;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,-1,sizeof(head)); tot=0; add(n+1,n+2,ans); add(n+2,n+1,ans); for(int i=1;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+1,i,p[i].d1); add(i,n+1,p[i].d1); p[i].d2=max(0.0,dis2(a,b,c2,p[i].x,p[i].y)-p[i].r); add(n+2,i,p[i].d2); add(i,n+2,p[i].d2); } for(int i=1;i<=n;i++){ for(int j=i+1;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
View Code

 

转载于:https://www.cnblogs.com/buerdepepeqi/p/9738703.html

你可能感兴趣的文章
SQL锁表语句 (转摘)
查看>>
python--递归、二分查找算法
查看>>
mysql5.7 user表没有password字段,如何重置root密码
查看>>
【转】SVN 与 GIT 详细对比
查看>>
UNITY 内存问题资料收集
查看>>
需求的最初形式:12306ng的需求小说
查看>>
python面试
查看>>
用Docker构建Nginx镜像
查看>>
spring注解-“@Scope”
查看>>
apache错误日志(error_log)记录等级
查看>>
通用的前端注册验证
查看>>
WPF 窗体中的 Canvas 限定范围拖动 鼠标滚轴改变大小
查看>>
django下的 restful规范 Drf框架 psotman的安装使用 及一些容易遗忘的小点
查看>>
Atitit.输入法配置说明v1 q229
查看>>
Atitit main函数的ast分析 数组参数调用的ast astview解析
查看>>
[转载]漫话:如何给女朋友介绍什么是死锁
查看>>
读书笔记——持有对象
查看>>
php header函数导出excel表格
查看>>
Jzoj1277最高的奶牛
查看>>
plsql中文乱码问题(显示问号)
查看>>