您的位置:首页 > 其它

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

2016-01-12 18:49 537 查看
题目大意:

曼哈顿最小距离生成树

算法讨论:

同上。

这回的模板真的准了。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 100000 + 5;
const int M = N * 8;
typedef long long ll;
const ll oo = 100000000000000LL;

int n, etot;
ll W = 0, c
;
int fa
, id
;
int A
, B
;

struct Point{
int x, y, id;
bool operator < (const Point &a)const {
if(a.x == x) return y < a.y;
return x < a.x;
}
}p
;

struct Edge{
int from, to;
ll dis;
bool operator < (const Edge &a)const {
return dis < a.dis;
}
}e[M];

int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}
void update(int x, ll val, int pos){
for(int i = x; i > 0; i -= (i&(-i))){
if(val < c[i]){
c[i] = val;
id[i] = pos;
}
}
}
int query(int pos, int up){
int res = -1;
ll val = oo;
for(int i = pos; i <= up; i += (i&(-i))){
if(c[i] < val){
val = c[i];
res = id[i];
}
}
return res;
}
void MST(){
int up;
for(int dir = 1; dir <= 4; ++ dir){
if(dir % 2 == 0)
for(int i = 1; i <= n; ++ i)
swap(p[i].x, p[i].y);
else if(dir == 3)
for(int i = 1; i <= n; ++ i)
p[i].x = -p[i].x;
sort(p + 1, p + n + 1);
for(int i = 1; i <= n; ++ i) A[i] = B[i] = (int) p[i].y - p[i].x;
sort(B + 1, B + n + 1);
up = unique(B + 1, B + n + 1) - B - 1;

for(int i = 1; i <= up; ++ i){
c[i] = oo; id[i] = -1;
}

for(int i = n; i >= 1; -- i){
A[i] = lower_bound(B + 1, B + up + 1, A[i]) - B;
int np = query(A[i], up);
if(np != -1){
++ etot;
e[etot].from = p[i].id;
e[etot].to = p[np].id;
e[etot].dis = abs(p[i].x - p[np].x) + abs(p[i].y - p[np].y);
}
update(A[i], p[i].x + p[i].y, i);
}
}

int have = 0;
sort(e + 1, e + etot + 1);
for(int i = 1; i <= n; ++ i) fa[i] = i;
for(int i = 1; i <= etot; ++ i){
int fx = find(e[i].from), fy = find(e[i].to);
if(fx != fy){
fa[fx] = fy;
++ have;
W += e[i].dis;
if(have == n-1) break;
}
}
}

int main(){
int cnt = 0;
while(scanf("%d", &n) && n){
++ cnt; etot = 0;
for(int i = 1; i <= n; ++ i){
scanf("%d%d", &p[i].x, &p[i].y);
p[i].id = i;
}
W = 0;
MST();
printf("Case %d: Total Weight = %lld\n", cnt, W);
}
return 0;
}


LA 3662
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: