hdu 4063 福州赛区网络赛 圆 ****
画几个图后,知道路径点集一定是起点终点加上圆与圆之间的交点,枚举每两个点之间是否能走,能走则连上线,然后求一遍最短路即可
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define sqr(x) ((x)*(x))
const double eps= 1e-;
const int maxc=;
const int maxp=;
const double inf=1e20;
double dsgn(double x)//return double
{
if(fabs(x)<eps)return ;
return x;
}
int isgn(double x)//return int
{
if(fabs(x)<eps)return ;
if(x<)return -;
return ;
}
struct point
{
double x, y;
point() {}
point(double xx, double yy):x(xx), y(yy) {}
double length() const
{
return sqrt(sqr(x)+sqr(y));
}
point set(const double &m) const
{
double len=length();
return point(x*m/len, y*m/len);
}
double sqrdist(const point &a)const
{
return sqr(a.x-x)+sqr(a.y-y);
}
double dist(const point &a)const
{
return sqrt(sqrdist(a));
}
} p[maxp];
struct line
{
double a, b, c;
line() {}
line(double ta=, double tb=-, double tc=):a(ta), b(tb), c(tc) {}
};
struct circle
{
point o;
double r;
} c[maxc];
int pn, cn;
double edge[maxp][maxp]; int cir_relation(circle c1, circle c2)//判断两圆关系
{
double d=c1.o.dist(c2.o);
int a=isgn(d-c1.r-c2.r);
int b=isgn(d-fabs(c1.r-c2.r));
if(a==)return -;//外切
if(b==)return -;//内切
if(a>)return ;//相离
if(b<)return ;//内含
return ;//相交
}
point line_intersect(point p1, point p2, point q1, point q2)
{
point ans=p1;
double t=((p1.x-q1.x)*(q1.y-q2.y)-(p1.y-q1.y)*(q1.x-q2.x))/
((p1.x-p2.x)*(q1.y-q2.y)-(p1.y-p2.y)*(q1.x-q2.x));
ans.x += (p2.x-p1.x)*t;
ans.y += (p2.y-p1.y)*t;
return ans;
}
void line_cross_circle(point p, point q, point o, double r, point &pp, point &qq)
{
point tmp=o;
tmp.x += p.y-q.y;
tmp.y += q.x-p.x;
tmp=line_intersect(tmp, o, p, q);
double t=sqrt(r*r - sqr(tmp.dist(o)))/(p.dist(q));
pp.x=tmp.x + (q.x-p.x)*t;
pp.y=tmp.y + (q.y-p.y)*t;
qq.x=tmp.x - (q.x-p.x)*t;
qq.y=tmp.y - (q.y-p.y)*t;
}
void circle_intersect(circle c1, circle c2, point &p1, point &p2)
{
point u, v;
double t, d;
d=c1.o.dist(c2.o);
t= (+ (sqr(c1.r) -sqr(c2.r))/sqr(d))/;
u.x= c1.o.x+ (c2.o.x-c1.o.x)*t;
u.y= c1.o.y+ (c2.o.y-c1.o.y)*t;
v.x= u.x+c1.o.y-c2.o.y;
v.y= u.y-c1.o.x+c2.o.x;
line_cross_circle(u, v, c1.o, c1.r, p1, p2);
}
point circle_tangent(circle c1, circle c2)
{
point t;
if(isgn(c1.o.dist(c2.o)-c1.r-c2.r)==)
{
t.x=(c1.r*c2.o.x + c2.r*c1.o.x)/(c1.r+c2.r);
t.y=(c1.r*c2.o.y + c2.r*c1.o.y)/(c1.r+c2.r);
return t;
}
t.x=(c1.r*c2.o.x-c2.r*c1.o.x)/(c1.r-c2.r);
t.y=(c1.r*c2.o.y-c2.r*c1.o.y)/(c1.r-c2.r);
return t;
}
void findallpoint()
{
int i, j, rel;
point p1, p2;
for(i=; i<=cn; i++)
for(j=i+; j<=cn; j++)
{
rel=cir_relation(c[i], c[j]);
if(rel==)
{
circle_intersect(c[i], c[j], p1, p2);
p[pn++]=p1;
p[pn++]=p2;
}
else if(rel<)
p[pn++]=circle_tangent(c[i], c[j]);
}
} point tmp[];
point qq[], base;
bool cmp(point a, point b)
{
return a.dist(base)<b.dist(base);
}
bool insideok(point a, point b)
{
for(int i=; i<=cn; i++)
{
if(isgn(c[i].r-a.dist(c[i].o))<)continue;
if(isgn(c[i].r-b.dist(c[i].o))<)continue;
return true;
}
return false;
}
double multiply(point sp, point ep, point op)
{
return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);
}
bool onsegment(point a, point u, point v)
{
return isgn(multiply(v, a, u))== && isgn((u.x-a.x)*(v.x-a.x))<= && isgn((u.y-a.y)*(v.y-a.y))<=;
} bool edgeok(point a, point b)
{
int i, j;
int cnt=, num; tmp[cnt++]=a;
point p1, p2;
for(i=; i<=cn; i++)
{
line_cross_circle(a, b, c[i].o, c[i].r, p1, p2);
if(onsegment(p1, a, b))tmp[cnt++]=p1;
if(onsegment(p2, a, b))tmp[cnt++]=p2;
}
tmp[cnt++]=b; base=a;
sort(tmp, tmp+cnt, cmp);
for(i=; i<cnt; i++)
if(!insideok(tmp[i-], tmp[i]))
return false;
return true;
}
void findalledge()
{
int i, j;
for(i=; i<pn; i++)
for(j=i+; j<pn; j++)
{
if(edgeok(p[i], p[j]))
edge[i][j]=edge[j][i]=p[i].dist(p[j]);
else
edge[i][j]=edge[j][i]=-;
}
}
bool has[maxp];
double dis[maxp];
void dijkstra()
{
int i, j, num;
double tmp;
for(i=; i<pn; i++)has[i]=false, dis[i]=inf;
dis[]=;
for(i=; i<pn; i++)
{
tmp=inf;
for(j=; j<pn; j++)
if(!has[j] && dis[j]<tmp)
{
tmp=dis[j];
num=j;
}
has[num]=true;
for(j=; j<pn; j++)
if(!has[j] && isgn(edge[num][j])>=)
dis[j]=min(dis[j], dis[num]+edge[num][j]);
}
if(dis[]<inf)printf("%.4lf\n", dis[]);
else printf("No such path.\n");
} void solve()
{
findallpoint();
findalledge();
dijkstra();
} int main()
{
int t, ca=;
scanf("%d", &t);
while(t--)
{
scanf("%d", &cn);
for(int i=; i<=cn; i++)
scanf("%lf%lf%lf", &c[i].o.x, &c[i].o.y, &c[i].r);
pn=;
p[pn++]=c[].o;
p[pn++]=c[cn].o;
printf("Case %d: ", ca++);
solve();
}
return ;
}
hdu 4063 福州赛区网络赛 圆 ****的更多相关文章
- hdu 4069 福州赛区网络赛I DLC ***
再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...
- hdu 4061 福州赛区网络赛A 数学 ***
a1/sum #include<cstdio> #include<iostream> #include<algorithm> #include<cstring ...
- hdu 4068 福州赛区网络赛H 排列 ***
拍的太慢了,很不满意 排完序之后,枚举自己和对手状态,若被击败,则再枚举自己下一个策略,直到可以击败对手所有的策略 #include<cstdio> #include<iostrea ...
- hdu 4070 福州赛区网络赛J 贪心 ***
优先发路程最长的 #include<cstdio> #include<iostream> #include<algorithm> #include<cstri ...
- HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)
HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...
- HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)
HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others) Memory Limit: ...
- ICPC 2018 徐州赛区网络赛
ACM-ICPC 2018 徐州赛区网络赛 去年博客记录过这场比赛经历:该死的水题 一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进. D. Easy Math 题意: ...
- 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 M. Frequent Subsets Problem【状态压缩】
2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 M. Frequent Subsets Problem 题意:给定N和α还有M个U={1,2,3,...N}的子集,求子集X个数,X满足:X是U ...
- HDU 5875 Function -2016 ICPC 大连赛区网络赛
题目链接 网络赛的水实在太深,这场居然没出线zzz,差了一点点,看到这道题的的时候就剩半个小时了.上面是官方的题意题解,打完了才知道暴力就可以过,暴力我们当时是想出来了的,如果稍稍再优化一下估计就过了 ...
随机推荐
- MyEclipse 优化
1.取消自动validation 有一堆,什么xml.jsp.jsf.js等等, 我们没有必要全部都去自动校验一下,只是需要的时候才会手工校验一下! 取消方法: windows-->perfer ...
- NUI四种提交数据方式c
方式一: 1)前端页面 2)逻辑流参数设置 方式二: 1)前端页面 2)逻辑流参数设置 方式三: 1)前端页面 2)逻辑流参数设置 方式四: 1)前端页面 2)逻辑流参数设置
- ubuntu 安装 phpmyadmin
安装步骤 1 apt-get install phpmyadmin 2 安装完后默认的安装位置是在/usr/share 而不是在/var/www 所以 需要将其链接到/var/www来,复制的话貌似需 ...
- Max Subsequence
一个sequence,里面都是整数,求最长的subsequence的长度,使得这个subsquence的最大值和最小值相差不超过1. 比如[1,3,2,2,5,2,3,7]最长的subsequence ...
- C#零碎知识汇总
1.1取时间差 时刻:DateTime 时差:TimeSpan 代码: DateTime time1 = DateTime.Now; textBox1.Text = time1.ToStri ...
- POJ 3752
http://poj.org/problem?id=3752 这是一道我觉得还蛮有意思的题目,不难,是个水题,但我也TLE了几次,感到很奇怪,这么简单的循环还TLE,最后一想,肯定是有几个例子我是没有 ...
- ios xib 中的 size class
需要阅读UITraitCollection的说明文档,先截图如下: 今天说说xib中的size class的简单设置,先看图 一共有9个小块,水平方向代表width,垂直方向代表height. 对于w ...
- 基于Hadoop 2.6.0运行数字排序的计算
上个博客写了Hadoop2.6.0的环境部署,下面写一个简单的基于数字排序的小程序,真正实现分布式的计算,原理就是对多个文件中的数字进行排序,每个文件中每个数字占一行,排序原理是按行读取后分块进行排序 ...
- ACM/ICPC 之 差分约束系统两道(ZOJ2770-POJ1201)
当对问题建立数学模型后,发现其是一个差分方程组,那么问题可以转换为最短路问题,一下分别选用Bellmanford-SPFA解题 ZOJ2770-Burn the Linked Camp //差分约束方 ...
- ui router 介绍
1. 路由规则 rap框架页面路由基于ui-router实现 1.1 ui-router 一个基本的路由状态如下所示: 路由配置: $stateProvider .state('po',{ url:' ...