LA 3662 Another Minimum Spanning Tree (曼哈顿距离最小生成树 模板)

题目大意:

曼哈顿最小距离生成树

算法讨论:

同上。

这回的模板真的准了。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <cstdio>
  6 using namespace std;
  7 const int N = 100000 + 5;
  8 const int M = N * 8;
  9 typedef long long ll;
 10 const ll oo = 100000000000000LL;
 11 
 12 int n, etot;
 13 ll W = 0, c[N];
 14 int fa[N], id[N];
 15 int A[N], B[N];
 16 
 17 struct Point{
 18     int x, y, id;
 19     bool operator < (const Point &a)const {
 20         if(a.x == x) return y < a.y;
 21         return x < a.x;
 22     }
 23 }p[N];
 24 
 25 struct Edge{
 26     int from, to;
 27     ll dis;
 28     bool operator < (const Edge &a)const {
 29         return dis < a.dis;
 30     }
 31 }e[M];
 32 
 33 int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}
 34 void update(int x, ll val, int pos){
 35     for(int i = x; i > 0; i -= (i&(-i))){
 36         if(val < c[i]){
 37             c[i] = val;
 38             id[i] = pos;
 39         }
 40     }
 41 }
 42 int query(int pos, int up){
 43     int res = -1;
 44     ll val = oo;
 45     for(int i = pos; i <= up; i += (i&(-i))){
 46         if(c[i] < val){
 47             val = c[i];
 48             res = id[i];
 49         }
 50     }
 51     return res;
 52 }
 53 void MST(){
 54     int up;
 55     for(int dir = 1; dir <= 4; ++ dir){
 56         if(dir % 2 == 0)
 57             for(int i = 1; i <= n; ++ i)
 58                 swap(p[i].x, p[i].y);
 59         else if(dir == 3)
 60             for(int i = 1; i <= n; ++ i)
 61                 p[i].x = -p[i].x;
 62         sort(p + 1, p + n + 1);
 63         for(int i = 1; i <= n; ++ i) A[i] = B[i] = (int) p[i].y - p[i].x;
 64         sort(B + 1, B + n + 1);
 65         up = unique(B + 1, B + n + 1) - B - 1;
 66         
 67         for(int i = 1; i <= up; ++ i){
 68             c[i] = oo; id[i] = -1;
 69         }
 70                 
 71         for(int i = n; i >= 1; -- i){
 72             A[i] = lower_bound(B + 1, B + up + 1, A[i]) - B;
 73             int np = query(A[i], up);
 74             if(np != -1){
 75                 ++ etot;
 76                 e[etot].from = p[i].id;
 77                 e[etot].to = p[np].id;
 78                 e[etot].dis = abs(p[i].x - p[np].x) + abs(p[i].y - p[np].y);
 79             }
 80             update(A[i], p[i].x + p[i].y, i);
 81         }
 82     }
 83     
 84     int have = 0;
 85     sort(e + 1, e + etot + 1);
 86     for(int i = 1; i <= n; ++ i) fa[i] = i;
 87     for(int i = 1; i <= etot; ++ i){
 88         int fx = find(e[i].from), fy = find(e[i].to);
 89         if(fx != fy){
 90             fa[fx] = fy;
 91             ++ have;
 92             W += e[i].dis;
 93             if(have == n-1) break;
 94         }
 95     }
 96 }
 97 
 98 int main(){
 99     int cnt = 0;
100     while(scanf("%d", &n) && n){
101         ++ cnt; etot = 0;
102         for(int i = 1; i <= n; ++ i){
103             scanf("%d%d", &p[i].x, &p[i].y);
104             p[i].id = i;
105         }
106         W = 0;
107         MST();
108         printf("Case %d: Total Weight = %lld\n", cnt, W);
109     }    
110     return 0;
111 }
LA 3662

 

posted @ 2016-01-12 18:49  漫步者。!~  阅读(250)  评论(0编辑  收藏  举报