传送门:http://arc076.contest.atcoder.jp/tasks/arc076_b

本题是一个图论问题——Manhattan距离最小生成树(MST)。

在一个平面网格上有n个格点,第i个格点的坐标是(xi,yi),构造一条连接点(a,b)和点(c,d)的边的代价是min{|a-c|,|b-d|}。对给定的n个格点构造连通图,使得总代价最小。

这是一个最小生成树(MST)问题。最“简单”的方法是,由n个结点构造一个无向完全图Kn,之后用Prim算法生成MST。这个程序的时间复杂度为O(n2logn),空间复杂度为O(n2)。对于105的数据规模,这个方法显然是不可取的。

考虑到Kruskal算法和Prim算法的时间复杂度均为O(ElogV),应尽可能地降低E的数量级(从Θ(n2)降至Θ(n))。

考虑以下的构造方式:对于点(a,b)和点(c,d),不构造代价为min{|a-c|,|b-d|}的边,而是构造两条边,其中一条边的代价为|a-c|,另一条边的代价为|b-d|。设存在i,j,k,使得xi<xj<xk,则连接ik的代价为|xi-xk|的边一定不会出现在MST中。因此,只需在坐标上相邻的两个结点之间构造边即可。这个构造方式构造的边数E=2(n-1),是Θ(n)的。具体的构造方式如下:

a.对结点按x坐标排序,在每一对相邻的点之间构造一条边,代价是相邻两点距离的x分量;

b.对结点按y坐标排序,在每一对相邻的点之间构造一条边,代价是相邻两点距离的y分量;

构造边的时间复杂度为O(nlogn),空间复杂度为O(n)。

之后,用Kruskal算法生成MST,时间复杂度为O(nlogn)。参考程序如下:

#include <bits/stdc++.h>
using namespace std; #define MAX_N 100010 struct point {int id, x, y;};
struct edge {int u, v, w;}; int n;
point p[MAX_N];
edge edgeset[ * MAX_N]; //disjoint set
int pa[MAX_N];
int rnk[MAX_N]; void init(void)
{
memset(pa, , sizeof(pa));
memset(rnk, , sizeof(rnk));
for (int i = ; i < n; i++) {
pa[i] = i;
rnk[i] = ;
}
} int find(int x)
{
if (pa[x] == x) return x;
else return pa[x] = find(pa[x]);
} void unite(int x, int y)
{
x = find(x);
y = find(y);
if (x == y) return;
if (rnk[x] < rnk[y]) pa[x] = y;
else {
pa[y] = x;
if (rnk[x] == rnk[y]) rnk[x]++;
}
} bool same(int x, int y)
{
return (find(x) == find(y));
} int abs(int a)
{
return a >= ? a: -a;
} bool cmp_x(point a, point b)
{
return a.x < b.x;
} bool cmp_y(point a, point b)
{
return a.y < b.y;
} bool cmp_edge(edge a, edge b)
{
return a.w < b.w;
} //kruskal minimum spanning tree
int mst(void)
{
init();
int res = ;
for (int i = ; i < * (n - ); i++) {
edge e = edgeset[i];
if (!same(e.u, e.v)) {
unite(e.u ,e.v);
res += e.w;
}
}
return res;
} int main(void)
{
scanf("%d", &n);
for (int i = ; i < n; i++) {
scanf("%d%d", &p[i].x, &p[i].y);
p[i].id = i;
}
sort(p, p + n, cmp_x);
for (int i = ; i < n - ; i++) {
edgeset[i].u = p[i].id;
edgeset[i].v = p[i + ].id;
edgeset[i].w = abs(p[i + ].x - p[i].x);
}
sort(p, p + n, cmp_y);
for (int i = ; i < n - ; i++) {
edgeset[i + n - ].u = p[i].id;
edgeset[i + n - ].v = p[i + ].id;
edgeset[i + n - ].w = abs(p[i + ].y - p[i].y);
}
sort(edgeset, edgeset + * (n - ), cmp_edge);
printf("%d\n", mst());
return ;
}

AtCoder ARC 076D - Built?的更多相关文章

  1. 【题解】Atcoder ARC#90 F-Number of Digits

    Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...

  2. AtCoder ARC 076E - Connected?

    传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c 平面上有一个R×C的网格,格点上可能写有数字1~N,每个数字出现两次.现在用一条曲线将一对相同的 ...

  3. AtCoder ARC 082E - ConvexScore

    传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c 本题是一个平面几何问题. 在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n} ...

  4. Atcoder ARC 082C/D

    C - Together 传送门:http://arc082.contest.atcoder.jp/tasks/arc082_a 本题是一个数学问题. 有一个长度为n的自然数列a[1..n],对于每一 ...

  5. AtCoder ABC 076D - AtCoder Express

    传送门:http://abc076.contest.atcoder.jp/tasks/abc076_d 本题是一个运动学问题——匀变速运动. 一个质点,从静止开始运动.按照速度限制,可将运动划分成n个 ...

  6. 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)

    题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...

  7. 【题解】Atcoder ARC#96 F-Sweet Alchemy

    首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...

  8. AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision

    题目传送门:ARC090E. 题意简述: 给定一张有 \(N\) 个点 \(M\) 条边的无向图.每条边有相应的边权,边权是正整数. 小 A 要从结点 \(S\) 走到结点 \(T\) ,而小 B 则 ...

  9. 【题解】Atcoder ARC#67 F-Yakiniku Restaurants

    觉得我的解法好简单,好优美啊QAQ 首先想想暴力怎么办.暴力的话,我们就枚举左右端点,然后显然每张购物券都取最大的值.这样的复杂度是 \(O(n ^{2} m)\) 的.但是这样明显能够感觉到我们重复 ...

随机推荐

  1. selenium使用chrome抓取自动消失弹框的方法

    selenium使用chrome抓取自动消失弹框的方法 转:https://blog.csdn.net/kennin19840715/article/details/76512394

  2. selenium IDE 回放报错

    解决:Selenium RC未启动,启动即可. java -jar selenium-server-standalone-2.25.0.jar 启动RC报错,提示找不到firefox的path,于是配 ...

  3. 【POJ 1201】 Intervals(差分约束系统)

    [POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: ...

  4. ASP原码加密工具介绍

    ASP原码加密工具介绍 总是会有非常多方法暴露ASP的原程序.造成数据库的password 路径都能够轻易被其它人搞到,所以对ASP程序实行加密处理是个不错的解决方法.以下来介绍一个工具假设大家感兴趣 ...

  5. Linux(redhat 5.8)下 安装jetty 部署 使用

    首先须要安装JDK,自行解决 下载jetty安装包http://dist.codehaus.org/jetty/ 我下载的是8.1.15 tar -xzvf *.tar.gz 解压完之后,基本就能够用 ...

  6. HDU 4099 Revenge of Fibonacci Trie+高精度

    Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: ...

  7. LMDB中的mmap、Copy On Write、MVCC深入理解——讲得非常好,常来看看!

    LMDB基本架构 lmdb的基本架构如下:  lmdb的基本做法是使用mmap文件映射,不管这个文件存储实在内存上还是在持久存储上.lmdb的所有读取操作都是通过mmap将要访问的文件只读的映射到虚拟 ...

  8. Codeforces--630C--Lucky Numbers(快速幂)

     C - Lucky Numbers Crawling in process... Crawling failed Time Limit:500MS     Memory Limit:65536K ...

  9. [APIO2008]DNA

    https://zybuluo.com/ysner/note/1158123 题面 戳我 解析 我们要求出第\(r\)种方案,莫过于看其前面什么时候有\(r-1\)种方案. 于是,我们要求出每种情况的 ...

  10. uva1084

    状压dp+凸包 并没有看出来凸包的性质 首先答案一定在凸包上,然后每个凸包的角加起来是一个圆,那么就相当于凸包周长加一个圆了.然后预处理,再状压dp计算即可. #include<bits/std ...