zoukankan      html  css  js  c++  java
  • poj3241 曼哈顿最小距离生成树第k大的边

    思路:

    已知:

    要生成曼哈顿距离最小生成树,一个点最多和四周8个点连线,那8个点分别是将那个点四周360度平分成8个区间,每个区间里面和那个点曼哈顿距离最小的点,所以如果有n个点,那么最多有4n条边,然后就可以用kruskal算法去做。

      1 #include <iostream>    //poj3241 曼哈顿距离最小生成树第k大的边
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <climits>
      6 #define mid ((l+r)>>1)
      7 using namespace std;
      8 
      9 int ent;
     10 
     11 int temp1,temp2,temp3;
     12 
     13 int fa[11000];
     14 
     15 class Point
     16 {
     17 public:
     18     int x,y,id;
     19 } point[11000];
     20 
     21 class Tree
     22 {
     23 public:
     24     int index,current;
     25 } tree[2200<<2];
     26 
     27 class Edge
     28 {
     29 public:
     30     int s,t,dis;
     31 } edge[44000];
     32 
     33 bool cmp(Point a,Point b)
     34 {
     35     if(a.x==b.x)
     36         return a.y<b.y;
     37     return a.x<b.x;
     38 }
     39 
     40 bool cmp2(Edge a,Edge b)
     41 {
     42     return a.dis<b.dis;
     43 }
     44 
     45 int get_ans(Point a)
     46 {
     47     return a.y-a.x+1100;
     48 }
     49 
     50 int get_dis(int a,int b)
     51 {
     52     return point[b].x+point[b].y-point[a].x-point[a].y;
     53 }
     54 
     55 void build(int l,int r,int n)
     56 {
     57     tree[n].index=INT_MAX;
     58     if(l==r)
     59     {
     60         tree[n].current=l;
     61         return;
     62     }
     63     build(l,mid,n<<1);
     64     build(mid+1,r,n<<1|1);
     65 }
     66 
     67 void update(int l,int r,int n,int current,int aim)
     68 {
     69     int ans=point[aim].x+point[aim].y;
     70     if(ans<tree[n].index)
     71         tree[n].index=ans;
     72     if(l==r)
     73     {
     74         if(ans==tree[n].index)
     75             tree[n].current=aim;
     76         return;
     77     }
     78     if(mid<current)
     79         update(mid+1,r,n<<1|1,current,aim);
     80     else update(l,mid,n<<1,current,aim);
     81 }
     82 
     83 void search(int l,int r,int n,int current,int aim)
     84 {
     85     if(l==r)
     86     {
     87         if(tree[n].index<temp1)
     88         {
     89             temp1=tree[n].index;
     90             temp2=tree[n].current;
     91         }
     92         return;
     93     }
     94     if(mid<current)
     95         search(mid+1,r,n<<1|1,current,aim);
     96     else if(l>=current)
     97     {
     98         if(tree[n<<1].index<tree[n<<1|1].index)
     99             search(l,mid,n<<1,current,aim);
    100         else search(mid+1,r,n<<1|1,current,aim);
    101     }
    102     else
    103     {
    104         if(tree[n<<1].index>=tree[n<<1|1].index)
    105             search(mid+1,r,n<<1|1,current,aim);
    106         else
    107         {
    108             search(l,mid,n<<1,current,aim);
    109             search(mid+1,r,n<<1|1,current,aim);
    110         }
    111     }
    112 }
    113 
    114 int find(int x)
    115 {
    116     int temp=x;
    117     while(x!=fa[x])
    118         x=fa[x];
    119     while(temp!=fa[temp])
    120     {
    121         temp=fa[temp];
    122         fa[temp]=x;
    123     }
    124     return x;
    125 }
    126 
    127 int pos[2200];
    128 bool sign[2200];
    129 int ans[2200];
    130 
    131 int main()
    132 {
    133     int n,k;
    134     while(cin>>n>>k)
    135     {
    136         int m=0;
    137         ent=0;
    138         memset(sign,false,sizeof(sign));
    139         for(int i=0; i<n; i++)
    140         {
    141             scanf("%d%d",&point[i].x,&point[i].y);
    142             point[i].id=i;
    143         }
    144         for(int tot=0; tot<4; tot++)
    145         {
    146             if(tot==2)
    147             {
    148                 for(int i=0; i<n; i++)
    149                     point[i].y=-point[i].y;
    150             }
    151             if(tot==1||tot==3)
    152             {
    153                 for(int i=0; i<n; i++)
    154                 {
    155                     point[i].x=point[i].x+point[i].y;
    156                     point[i].y=point[i].x-point[i].y;
    157                     point[i].x=point[i].x-point[i].y;
    158                 }
    159             }
    160             for(int i=0; i<n; i++)
    161             {
    162                 int temp=get_ans(point[i]);
    163                 if(!sign[temp])
    164                 {
    165                     pos[m++]=temp;
    166                     sign[temp]=true;
    167                 }
    168             }
    169             sort(pos,pos+m);
    170             for(int i=0; i<m; i++)
    171             {
    172                 ans[pos[i]]=i;
    173             }
    174             sort(point,point+n,cmp);
    175             build(0,m-1,1);
    176             for(int i=n-1; i>0; i--)
    177             {
    178                 update(0,m-1,1,ans[get_ans(point[i])],i);
    179                 temp1=INT_MAX;
    180                 search(0,m-1,1,ans[get_ans(point[i-1])],i-1);
    181                 if(temp1!=INT_MAX)
    182                 {
    183                     edge[ent].s=point[i-1].id,edge[ent].t=point[temp2].id;
    184                     edge[ent++].dis=get_dis(i-1,temp2);
    185                 }
    186             }
    187         }
    188         sort(edge,edge+ent,cmp2);
    189         for(int i=0; i<=n; i++)
    190             fa[i]=i;
    191         int tot=0;
    192         for(int i=0; i<ent; i++)
    193         {
    194             int x=find(edge[i].s);
    195             int y=find(edge[i].t);
    196             if(x==y)
    197                 continue;
    198             else
    199             {
    200                 fa[y]=x;
    201                 tot++;
    202             }
    203             if(tot==n-k)
    204             {
    205                 cout<<edge[i].dis<<endl;
    206                 break;
    207             }
    208         }
    209     }
    210     return 0;
    211 }
    View Code
  • 相关阅读:
    ajax提交Form
    MySQL新建用户,授权,删除用户,修改密码总结
    php 数组操作类(整合 给意见)
    PHP基于数组的分页函数(核心函数array_slice())
    php生成table表格
    百度地图定位
    python-redis-订阅和发布
    宿主机-免密登录Docker容器
    docker-文件系统出错处理
    python-redis集合模式
  • 原文地址:https://www.cnblogs.com/lthb/p/5010203.html
Copyright © 2011-2022 走看看