LA 3662 Another Minimum Spanning Tree (曼哈顿距离最小生成树 模板)
2016-01-12 18:49
537 查看
题目大意:
曼哈顿最小距离生成树
算法讨论:
同上。
这回的模板真的准了。
LA 3662
曼哈顿最小距离生成树
算法讨论:
同上。
这回的模板真的准了。
#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
相关文章推荐
- android基础学习002_Android LayoutInflater详解
- Android 性能优化实践
- [已经解决]想实现限制192.168.43.1~192.168.43.255对公网的访问,请问谁用iptables或者route 能实现?
- 【转】YUV420P的格式以及转换为RGB565的代码(Android摄像头的输出一般为YUV420P)
- 2016年01月12日公司项目开发记录
- quip共同合作
- 【转】iOS开发-文件管理(一)
- 搭建linux虚拟环境
- 【Linux驱动】linux内核模块简介
- sorl创建core和删除core
- 【HNOI2008】GT考试
- 获取字符串首字母
- jquery实现横向图片滚动
- 【转】WPF MultiBinding 和 IMultiValueConverter
- Educational Codeforces Round 5(D)尺取+SET
- redis集群搭建
- hadoop 2.6.0 LightWeightGSet源代码分析
- 返回数据给上一个活动
- 对HDFS上多个文件并行执行grep操作
- Unity3D游戏开发之如何发布Android游戏