zoukankan      html  css  js  c++  java
  • hdu3228Island Explorer

    链接

    给你两条线及两条线上的点,求最小生成树。

    可以挨个枚举一条线上的点,三分出另一条线上离他最近的点进行连边。

    注意N、M可能为0

    debug了1天半,至今不知道原始二分版本错在哪里。。

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 using namespace std;
     11 #define N 50010
     12 #define LL long long
     13 #define INF 0xfffffff
     14 const double eps = 1e-8;
     15 const double pi = acos(-1.0);
     16 const double inf = ~0u>>2;
     17 struct point
     18 {
     19     double x,y;
     20     int id;
     21     point(double x=0,double y = 0):x(x),y(y) {}
     22 } p[N],q[N];
     23 struct node
     24 {
     25     int u,v;
     26     double w;
     27 } ed[N<<4];
     28 int fa[N],g;
     29 double t1[N],t2[N];
     30 point a,b,c,d;
     31 typedef point pointt;
     32 point operator -(point a,point b)
     33 {
     34     return point(a.x-b.x,a.y-b.y);
     35 }
     36 int dcmp(double x)
     37 {
     38     if(fabs(x)<eps) return 0;
     39     return x<0?-1:1;
     40 }
     41 
     42 double dis(point a)
     43 {
     44     return sqrt(a.x*a.x+a.y*a.y);
     45 }
     46 bool cmmp(node ta,node tb)
     47 {
     48     return ta.w<tb.w;
     49 }
     50 int findx(int x)
     51 {
     52     if(x!=fa[x])
     53         fa[x] = findx(fa[x]);
     54     return fa[x];
     55 }
     56 void add(point ta,point tb)
     57 {
     58     ed[++g].u = ta.id;
     59     ed[g].v = tb.id;
     60     ed[g].w = dis(ta-tb);
     61 }
     62 int main()
     63 {
     64     // freopen("data.in","r",stdin);
     65     // freopen("data.out","w",stdout);
     66     int t,i,n,m;
     67     int kk = 0;
     68     cin>>t;
     69     while(t--)
     70     {
     71         scanf("%d%d",&n,&m);
     72         scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
     73         for(i = 0; i <= n+m ; i++)
     74             fa[i] = i;
     75         for(i = 0; i < n; i++)
     76         {
     77             scanf("%lf",&t1[i]);
     78 
     79             // cout<<p[i].x<<" "<<p[i].y<<endl;
     80         }
     81         for(i = 0; i< m; i++)
     82         {
     83             scanf("%lf",&t2[i]);
     84 
     85         }
     86         sort(t1,t1+n);
     87         sort(t2,t2+m);
     88         int h=0;
     89         for(i=0;i<n;i++)
     90             if(i==n-1||t1[i]!=t1[i+1])
     91                 t1[h++]=t1[i];
     92         n=h;
     93         h=0;
     94         for(i=0;i<m;i++)
     95             if(i==m-1||t2[i]!=t2[i+1])
     96                 t2[h++]=t2[i];
     97         m=h;
     98         for(i = 0; i < n;i++)
     99         {
    100              p[i] = point(a.x*t1[i]+b.x*(1-t1[i]),a.y*t1[i]+b.y*(1-t1[i]));
    101              p[i].id = i+1;
    102         }
    103         for(i = 0 ; i < m ; i++)
    104         {
    105             q[i] = point(c.x*t2[i]+d.x*(1-t2[i]),c.y*t2[i]+d.y*(1-t2[i]));
    106             q[i].id = i+n+1;
    107         }
    108         g = 0;
    109         double sum1 = 0,sum2 = 0;
    110         for(i = 0 ; i < n-1 ; i++)
    111         {
    112             add(p[i],p[i+1]);
    113             sum1+=dis(p[i]-p[i+1]);
    114         }
    115         for(i = 0 ; i < m-1 ; i++)
    116         {
    117             add(q[i],q[i+1]);
    118             sum2+=dis(q[i]-q[i+1]);
    119         }
    120         if(n==0||m==0)
    121         {
    122 
    123             printf("Case #%d: %.3lf
    ",++kk,sum1+sum2);
    124             continue;
    125         }
    126         for(i = 0; i < n; i++)
    127         {
    128 //            point pp ;
    129 //            if(dcmp(c.x-d.x)==0)
    130 //            pp = point(c.x,p[i].y);
    131 //            else
    132 //            pp = dispoint(c,d,p[i]);
    133 //            if(dcmp(pp.x-min(c.x,d.x))<=0||dcmp(pp.x-max(c.x,d.x))>=0)
    134 //            {
    135 //                add(i,n+1);
    136 //                if(n+2<n+m)
    137 //                add(i,n+2);
    138 //                if(n+m-1>n+1)
    139 //                add(i,n+m-1);
    140 //                add(i,n+m);
    141 //                continue;
    142 //            }
    143 //            int k = find(n+1,n+m,c,dis(pp-c));
    144             // cout<<p[k].id<<" "<<pp.x<<" "<<pp.y<<endl;
    145 //            add(i,k);
    146 //            if(k!=n+1)
    147 //            add(i,k-1);
    148 //            if(k!=n+m)
    149 //            add(i,k+1);
    150             int l, r;
    151             l = 0;
    152             r = m-1;
    153             while (r - l > 1)
    154             {
    155                 int mid1 = (r + l) >> 1;
    156                 int mid2 = (mid1 + r) >> 1;
    157                 if (dis(p[i]-q[mid1]) > dis(p[i]-q[mid2]))
    158                     l = mid1;
    159                 else
    160                     r = mid2;
    161             }
    162 //            int k = find(1,n,a,dis(pp-a));
    163             add(p[i],q[l]);
    164             add(p[i],q[r]);
    165             if(l-1>=0)
    166                 add(p[i],q[l-1]);
    167             if(r+1<=m-1)
    168                 add(p[i],q[r+1]);
    169         }
    170         sort(ed+1,ed+g+1,cmmp);
    171         int num = 0;
    172         double sum = 0;
    173         for(i = 1; i <= g; i++)
    174         {
    175             int tx = findx(ed[i].u);
    176             int ty = findx(ed[i].v);
    177             if(tx!=ty)
    178             {
    179                 fa[tx] = ty;
    180                 num++;
    181                 sum+=ed[i].w;
    182             }
    183         }
    184         printf("Case #%d: %.3f
    ",++kk,sum);
    185     }
    186     return 0;
    187 }
    View Code
  • 相关阅读:
    Oracle 分区索引
    linux中select网络通信
    AVL树,红黑树,B-B+树,Trie树原理和应用
    zoj1232Adventure of Super Mario(图上dp)
    怎样更改Linux中默认的openjdk为自己安装的JDK
    食用甜玉米:增进健康,老少皆宜
    设计模式【3】:抽象工厂【创建对象】
    centos 7 安装JDK (Linux安装jdk)
    微信支付v3开发(5) 扫码并输入金额支付
    微信支付v3开发(6) 收货地址共享接口
  • 原文地址:https://www.cnblogs.com/shangyu/p/3918963.html
Copyright © 2011-2022 走看看