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

 #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. c#的问号?和双问号??

    1.问号?表示该变量可以为空 int? a=new int?(); Console.Writeline(a);//a是null 等价于: int? a=null; 也等价于下面这行,表示该变量默认为n ...

  2. Android蓝牙连接以及数据接收发送

    1.加入权限 <uses-feature android:name="android.hardware.bluetooth_le" android:required=&quo ...

  3. AFNetworking 2.5.0版本的使用

    http://www.mamicode.com/info-detail-477899.html AFNetworking 2.5.0版本的使用 http://afnetworking.com/ htt ...

  4. C#系统委托之Action And Func

    Action Action<T> Func Func<T> Action:封装一个方法,该方法不具有参数并且不返回值 public delegate void Action() ...

  5. 【leetcode】Word Search

    Word Search Given a 2D board and a word, find if the word exists in the grid. The word can be constr ...

  6. How to take partial screenshot with Selenium WebDriver in python

    from selenium import webdriver from PIL import Image fox = webdriver.Firefox() fox.get('http://stack ...

  7. c++ 文件utf-8格式

    #include <stdio.h> int i = 0; while (i < 20) {    i++;    WriteLog("d:\\log.txt", ...

  8. Enum:EXTENDED LIGHTS OUT(POJ 1222)

    亮灯 题目大意:有一个5*6的灯组,按一盏灯会让其他上下左右4栈和他自己灯变为原来相反的状态,要怎么按才会把所有的灯都按灭? 3279翻版题目,不多说,另外这一题还可以用其他方法,比如DFS,BFS, ...

  9. unbutu下搭建FTP服务

    安装 apt-get install vsftpd 启动 service vsftpd start 第一次连接的时候出了点问题,报了一个 login incorrect 530的连接错误 然后百度了一 ...

  10. .NET微信公众号开发-3.0查询自定义菜单

    一.前言 前面我们已经创建好了我们的自定义菜单.那么我们现在要如何查询我们自定义的菜单.原理都是一样的,而且都是相当简单,只是接口地址文档换掉了. 2.0开始编码 同样我们首先创建好我的查询页面,在这 ...