zoukankan      html  css  js  c++  java
  • hdu 4063 福州赛区网络赛 圆 ****

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

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<algorithm>
      6 using namespace std;
      7 #define sqr(x) ((x)*(x))
      8 const double eps= 1e-6;
      9 const int maxc=30;
     10 const int maxp=1000;
     11 const double inf=1e20;
     12 double dsgn(double x)//return double
     13 {
     14     if(fabs(x)<eps)return 0;
     15     return x;
     16 }
     17 int isgn(double x)//return int
     18 {
     19     if(fabs(x)<eps)return 0;
     20     if(x<0)return -1;
     21     return 1;
     22 }
     23 struct point
     24 {
     25     double x, y;
     26     point() {}
     27     point(double xx, double yy):x(xx), y(yy) {}
     28     double length() const
     29     {
     30         return sqrt(sqr(x)+sqr(y));
     31     }
     32     point set(const double &m) const
     33     {
     34         double len=length();
     35         return point(x*m/len, y*m/len);
     36     }
     37     double sqrdist(const point &a)const
     38     {
     39         return sqr(a.x-x)+sqr(a.y-y);
     40     }
     41     double dist(const point &a)const
     42     {
     43         return sqrt(sqrdist(a));
     44     }
     45 } p[maxp];
     46 struct line
     47 {
     48     double a, b, c;
     49     line() {}
     50     line(double ta=1,  double tb=-1,  double tc=0):a(ta), b(tb), c(tc) {}
     51 };
     52 struct circle
     53 {
     54     point o;
     55     double r;
     56 } c[maxc];
     57 int pn, cn;
     58 double edge[maxp][maxp];
     59 
     60 int cir_relation(circle c1, circle c2)//判断两圆关系
     61 {
     62     double d=c1.o.dist(c2.o);
     63     int a=isgn(d-c1.r-c2.r);
     64     int b=isgn(d-fabs(c1.r-c2.r));
     65     if(a==0)return -2;//外切
     66     if(b==0)return -1;//内切
     67     if(a>0)return 2;//相离
     68     if(b<0)return 1;//内含
     69     return 0;//相交
     70 }
     71 point line_intersect(point p1, point p2, point q1, point q2)
     72 {
     73     point ans=p1;
     74     double t=((p1.x-q1.x)*(q1.y-q2.y)-(p1.y-q1.y)*(q1.x-q2.x))/
     75              ((p1.x-p2.x)*(q1.y-q2.y)-(p1.y-p2.y)*(q1.x-q2.x));
     76     ans.x += (p2.x-p1.x)*t;
     77     ans.y += (p2.y-p1.y)*t;
     78     return ans;
     79 }
     80 void line_cross_circle(point p, point q, point o, double r, point &pp, point &qq)
     81 {
     82     point tmp=o;
     83     tmp.x += p.y-q.y;
     84     tmp.y += q.x-p.x;
     85     tmp=line_intersect(tmp, o, p, q);
     86     double t=sqrt(r*r - sqr(tmp.dist(o)))/(p.dist(q));
     87     pp.x=tmp.x + (q.x-p.x)*t;
     88     pp.y=tmp.y + (q.y-p.y)*t;
     89     qq.x=tmp.x - (q.x-p.x)*t;
     90     qq.y=tmp.y - (q.y-p.y)*t;
     91 }
     92 void circle_intersect(circle c1, circle c2, point &p1, point &p2)
     93 {
     94     point u, v;
     95     double t, d;
     96     d=c1.o.dist(c2.o);
     97     t= (1+ (sqr(c1.r) -sqr(c2.r))/sqr(d))/2;
     98     u.x= c1.o.x+ (c2.o.x-c1.o.x)*t;
     99     u.y= c1.o.y+ (c2.o.y-c1.o.y)*t;
    100     v.x= u.x+c1.o.y-c2.o.y;
    101     v.y= u.y-c1.o.x+c2.o.x;
    102     line_cross_circle(u, v, c1.o, c1.r, p1, p2);
    103 }
    104 point circle_tangent(circle c1, circle c2)
    105 {
    106     point t;
    107     if(isgn(c1.o.dist(c2.o)-c1.r-c2.r)==0)
    108     {
    109         t.x=(c1.r*c2.o.x + c2.r*c1.o.x)/(c1.r+c2.r);
    110         t.y=(c1.r*c2.o.y + c2.r*c1.o.y)/(c1.r+c2.r);
    111         return t;
    112     }
    113     t.x=(c1.r*c2.o.x-c2.r*c1.o.x)/(c1.r-c2.r);
    114     t.y=(c1.r*c2.o.y-c2.r*c1.o.y)/(c1.r-c2.r);
    115     return t;
    116 }
    117 void findallpoint()
    118 {
    119     int i, j, rel;
    120     point p1, p2;
    121     for(i=1; i<=cn; i++)
    122         for(j=i+1; j<=cn; j++)
    123         {
    124             rel=cir_relation(c[i], c[j]);
    125             if(rel==0)
    126             {
    127                 circle_intersect(c[i], c[j], p1, p2);
    128                 p[pn++]=p1;
    129                 p[pn++]=p2;
    130             }
    131             else if(rel<0)
    132                 p[pn++]=circle_tangent(c[i], c[j]);
    133         }
    134 }
    135 
    136 point tmp[100];
    137 point qq[3], base;
    138 bool cmp(point a, point b)
    139 {
    140     return a.dist(base)<b.dist(base);
    141 }
    142 bool insideok(point a, point b)
    143 {
    144     for(int i=1; i<=cn; i++)
    145     {
    146         if(isgn(c[i].r-a.dist(c[i].o))<0)continue;
    147         if(isgn(c[i].r-b.dist(c[i].o))<0)continue;
    148         return true;
    149     }
    150     return false;
    151 }
    152 double multiply(point sp, point ep, point op)
    153 {
    154     return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);
    155 }
    156 bool onsegment(point a, point u, point v)
    157 {
    158     return isgn(multiply(v, a, u))==0 && isgn((u.x-a.x)*(v.x-a.x))<=0 && isgn((u.y-a.y)*(v.y-a.y))<=0;
    159 }
    160 
    161 bool edgeok(point a, point b)
    162 {
    163     int i, j;
    164     int cnt=0, num;
    165 
    166     tmp[cnt++]=a;
    167     point p1, p2;
    168     for(i=1; i<=cn; i++)
    169     {
    170         line_cross_circle(a, b, c[i].o, c[i].r, p1, p2);
    171         if(onsegment(p1, a, b))tmp[cnt++]=p1;
    172         if(onsegment(p2, a, b))tmp[cnt++]=p2;
    173     }
    174     tmp[cnt++]=b;
    175 
    176     base=a;
    177     sort(tmp, tmp+cnt, cmp);
    178     for(i=1; i<cnt; i++)
    179         if(!insideok(tmp[i-1], tmp[i]))
    180             return false;
    181     return true;
    182 }
    183 void findalledge()
    184 {
    185     int i, j;
    186     for(i=0; i<pn; i++)
    187         for(j=i+1; j<pn; j++)
    188         {
    189             if(edgeok(p[i], p[j]))
    190                 edge[i][j]=edge[j][i]=p[i].dist(p[j]);
    191             else
    192                 edge[i][j]=edge[j][i]=-1;
    193         }
    194 }
    195 bool has[maxp];
    196 double dis[maxp];
    197 void dijkstra()
    198 {
    199     int i, j, num;
    200     double tmp;
    201     for(i=0; i<pn; i++)has[i]=false, dis[i]=inf;
    202     dis[0]=0;
    203     for(i=0; i<pn; i++)
    204     {
    205         tmp=inf;
    206         for(j=0; j<pn; j++)
    207             if(!has[j] && dis[j]<tmp)
    208             {
    209                 tmp=dis[j];
    210                 num=j;
    211             }
    212         has[num]=true;
    213         for(j=0; j<pn; j++)
    214             if(!has[j] && isgn(edge[num][j])>=0)
    215                 dis[j]=min(dis[j], dis[num]+edge[num][j]);
    216     }
    217     if(dis[1]<inf)printf("%.4lf
    ", dis[1]);
    218     else printf("No such path.
    ");
    219 }
    220 
    221 void solve()
    222 {
    223     findallpoint();
    224     findalledge();
    225     dijkstra();
    226 }
    227 
    228 int main()
    229 {
    230     int t, ca=1;
    231     scanf("%d", &t);
    232     while(t--0)
    233     {
    234         scanf("%d", &cn);
    235         for(int i=1; i<=cn; i++)
    236             scanf("%lf%lf%lf", &c[i].o.x, &c[i].o.y, &c[i].r);
    237         pn=0;
    238         p[pn++]=c[1].o;
    239         p[pn++]=c[cn].o;
    240         printf("Case %d: ", ca++);
    241         solve();
    242     }
    243     return 0;
    244 }
  • 相关阅读:
    C#写文本文件,如何换行(添加换行符)
    C#使用oledb操作excel文件的方法
    winform之combobox
    vs2010快捷键
    可以下载一些书籍代码的网站
    对php和java里面的static函数和static的一些理解
    10.4-CMake find 模块
    6.25-Git 技巧
    6.4-Git Command
    2.25-CMake Tutorial
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4730142.html
Copyright © 2011-2022 走看看