UVALive--3662(曼哈顿距离,MST)

2015-04-30 14:37:52

题目:裸题,但是poj的程序贴过来竟然过不了.... 让我发现了一个细节错误:int sz = unique(a + 1,a + n + 1) - a - 1; 最后那个-1不能丢。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cstdlib>
  4 #include <cmath>
  5 #include <vector>
  6 #include <map>
  7 #include <set>
  8 #include <stack>
  9 #include <queue>
 10 #include <string>
 11 #include <iostream>
 12 #include <algorithm>
 13 using namespace std;
 14 
 15 #define MEM(a,b) memset(a,b,sizeof(a))
 16 #define REP(i,n) for(int i=0;i<(n);++i)
 17 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
 18 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
 19 #define MP(a,b) make_pair(a,b)
 20 #define PB(a) push_back(a)
 21 
 22 typedef long long ll;
 23 typedef pair<int,int> pii;
 24 const double eps = 1e-8;
 25 const int INF = (1 << 30) - 1;
 26 const int MAXN = 100010;
 27 
 28 int N,ecnt;
 29 int fa[MAXN],A[MAXN],B[MAXN];
 30 
 31 struct edge{
 32     int u,v,c;
 33     bool operator < (const edge a) const{
 34         return c < a.c;
 35     }
 36 }e[4 * MAXN];
 37 
 38 void Add_edge(int u,int v,int c){
 39     e[++ecnt].u = u;
 40     e[ecnt].v = v;
 41     e[ecnt].c = c;
 42 }
 43 
 44 struct Node{
 45     int x,y,id;
 46     bool operator < (const Node a) const{
 47         return x == a.x ? y < a.y : x < a.x;
 48     }
 49 }p[MAXN];
 50 
 51 struct BIT{
 52     int c[MAXN],ps[MAXN],tmax;
 53     void init(int tmp){
 54         tmax = tmp;
 55         FOR(i,1,tmax) c[i] = INF;
 56         MEM(ps,-1);
 57     }
 58     int lowbit(int x){ return x & (-x); }
 59     void update(int x,int d,int pos){
 60         while(x){
 61             if(d < c[x]){
 62                 c[x] = d;
 63                 ps[x] = pos;
 64             }
 65             x -= lowbit(x);
 66         }
 67     }
 68     int get(int x){
 69         int res = INF,pos = -1;
 70         while(x <= tmax){
 71             if(c[x] < res){
 72                 res = c[x];
 73                 pos = ps[x];
 74             }
 75             x += lowbit(x);
 76         }
 77         return pos;
 78     }
 79 }bit;
 80 
 81 int Dis(int a,int b){ return abs(p[a].x - p[b].x) + abs(p[a].y - p[b].y); }
 82 int Find(int x){ return fa[x] == x ? x : fa[x] = Find(fa[x]); }
 83 
 84 ll Manhattan_mst(){
 85     for(int dir = 1; dir <= 4; ++dir){
 86         //四种变换:(1) none , (2) y=x , (3) y=0 , (4) y=x
 87         if(dir == 2 || dir == 4)
 88             FOR(i,1,N) swap(p[i].x,p[i].y);
 89         else if(dir == 3)
 90             FOR(i,1,N) p[i].y = -p[i].y;
 91         sort(p + 1,p + N + 1); //sort by x
 92         FOR(i,1,N) A[i] = B[i] = p[i].y - p[i].x; //离散化
 93         sort(B + 1,B + N + 1);
 94         int sz = unique(B + 1,B + N + 1) - B - 1;
 95         //初始化反树状数组
 96         bit.init(sz);
 97         for(int i = N; i >= 1; --i){ //从 x 大的开始考虑
 98             int pos = lower_bound(B + 1,B + sz + 1,A[i]) - B;
 99             int ans = bit.get(pos); //比当前 y-x 大的最小 x+y 位置
100             if(ans != -1) Add_edge(p[i].id,p[ans].id,Dis(i,ans));//i找到匹配ans
101             bit.update(pos,p[i].x + p[i].y,i);
102         }
103     }
104     //Kruskal
105     ll res = 0;
106     sort(e + 1,e + ecnt + 1);
107     FOR(i,1,N) fa[i] = i;
108     FOR(i,1,ecnt){
109         int x = Find(e[i].u);
110         int y = Find(e[i].v);
111         if(x != y){
112             fa[y] = x;
113             res += (ll)e[i].c;
114         }
115     }
116     return res;
117 }
118 
119 int main(){
120     int  tt = 0;
121     while(scanf("%d",&N) != EOF && N){
122         FOR(i,1,N){
123             scanf("%d%d",&p[i].x,&p[i].y);
124             p[i].id = i;
125         }
126         ecnt = 0;
127         printf("Case %d: Total Weight = ",++tt);
128         printf("%lld\n",Manhattan_mst());
129     }
130     return 0;
131 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4468863.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值