画几个图后,知道路径点集一定是起点终点加上圆与圆之间的交点,枚举每两个点之间是否能走,能走则连上线,然后求一遍最短路即可

 #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 福州赛区网络赛 圆 ****的更多相关文章

  1. hdu 4069 福州赛区网络赛I DLC ***

    再遇到一个DLC就刷个专题 #include <stdio.h> #include <string.h> #include <iostream> #include ...

  2. hdu 4061 福州赛区网络赛A 数学 ***

    a1/sum #include<cstdio> #include<iostream> #include<algorithm> #include<cstring ...

  3. hdu 4068 福州赛区网络赛H 排列 ***

    拍的太慢了,很不满意 排完序之后,枚举自己和对手状态,若被击败,则再枚举自己下一个策略,直到可以击败对手所有的策略 #include<cstdio> #include<iostrea ...

  4. hdu 4070 福州赛区网络赛J 贪心 ***

    优先发路程最长的 #include<cstdio> #include<iostream> #include<algorithm> #include<cstri ...

  5. HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)

    HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...

  6. HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛)

    HDU 4046 Panda (ACM ICPC 2011北京赛区网络赛) Panda Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: ...

  7. ICPC 2018 徐州赛区网络赛

    ACM-ICPC 2018 徐州赛区网络赛  去年博客记录过这场比赛经历:该死的水题  一年过去了,不被水题卡了,但难题也没多做几道.水平微微有点长进.     D. Easy Math 题意:   ...

  8. 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 ...

  9. HDU 5875 Function -2016 ICPC 大连赛区网络赛

    题目链接 网络赛的水实在太深,这场居然没出线zzz,差了一点点,看到这道题的的时候就剩半个小时了.上面是官方的题意题解,打完了才知道暴力就可以过,暴力我们当时是想出来了的,如果稍稍再优化一下估计就过了 ...

随机推荐

  1. Java拼接批量新增SQL语句

    StringBuffer addSql = new StringBuffer(1000); int batchSize = 50; int executeTime = 0; SimpleDateFor ...

  2. ajaxfileupload回到json带<pre>

    ajaxfileupload返回json带<pre> 老系统,将文件上传方式修改为ajax上传,调用ajaxfileupload.js 出错现象: 文件正常提交,后台接收正常,action ...

  3. 外键约束 以及 数据库中实体的对应关系(1==1,1==n,n==n)

    1.1.1 外键约束 Create database day16; Use day16; 创建部门表: create table dept( did int primary key auto_incr ...

  4. ABAP 内表的行列转换-发货通知单-SLIS

    REPORT Z_TEST_COL_TO_ROW. TYPE-POOLS: slis. TABLES: VTTP,LIPS,LIKP,KNA1 ,VTTK. DATA: gd_fieldcat TYP ...

  5. GCD 大中枢派发 简单应用实例

    @interface ViewController () { UIImageView* iv; UIButton* btn; UILabel* lbl; } @end @implementation ...

  6. java基础学习05(面向对象基础01--类实例分析)

    面向对象基础01(类实例分析) 实现的目标 1.如何分析一个类(类的基本分析思路) 分析的思路 1.根据要求写出类所包含的属性2.所有的属性都必须进行封装(private)3.封装之后的属性通过set ...

  7. 开始使用 Fresco

    如果你仅仅是想简单下载一张网络图片,在下载完成之前,显示一张占位图,那么简单使用 SimpleDraweeView 即可. 在加载图片之前,你必须初始化Fresco类.你只需要调用Fresco.ini ...

  8. DREAMWEAVER

    女孩儿!!!Coding之路,你没有什么不一样的!!!! 1024,程序员的节日,开会的时候,你对负责人说今天是我们的节日哎~~结果,得到的是负责人冷冰冰的眼神:“你还真把自己当程序员了!?” 一阵愣 ...

  9. 【编程题目】n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始

    第 18 题(数组):题目:n 个数字(0,1,…,n-1)形成一个圆圈,从数字 0 开始,每次从这个圆圈中删除第 m 个数字(第一个为当前数字本身,第二个为当前数字的下一个数字).当一个数字删除后, ...

  10. [Android Pro] APK

    svn updatesvn status ls -alsvn log --limit 8 > RELEASE_NOTE.txt cat RELEASE_NOTE.txt chmod a+x gr ...