传送门: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. 【Nginx】模块化设计

    高度模块化的设计是Nginx的架构基础.全部模块都是以ngx_module_t结构体表示,该结构体内部定义了7个回调方法.它们负责模块的初始化和退出.commands成员是一个包括有ngx_comma ...

  2. selenium清空默认文字

    默认输入框 鼠标点击上去还有文案 直接用 clear不可以

  3. 黑马程序猿——————java基础

    一.软件开发 软件是什么? 软件是简单的来说,计算机数据和指令的集合,数据(比方年龄,性别).指令及时告诉计算机怎样对他进行处理.计算机但是没有人那么聪明啊! 二.图形化界面(GUI),主要特点就是. ...

  4. DM8168 IPNC Boa移植

    1.交叉编译openssL 下载openssL-1.0.0.tar.gz在虚拟机下进行交叉编译,生成libcrypto.a及libssl.a.将这两个文件复制到DVRRDK_03.00.00.00/b ...

  5. 从零開始学Xamarin.Forms(二) 环境搭建、创建项目

    一.环境搭建 Windows下环境搭建:     1.下载并安装jdk.Android SDK和NDK.当然还须要 VS2013 update 2(VS2010.VS2012均可)以上. a.  最新 ...

  6. LeetCode 28 Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. 思路:1.先将被除数和除数转化为long的非负 ...

  7. luogu2341 [HAOI2006]受欢迎的牛

    题目大意 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜欢B,B喜欢C,那么A也喜欢C.牛 ...

  8. 使用powershell来设置时间

    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/set-date?view=powers ...

  9. P1043 数字游戏

    P1043 数字游戏 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n ...

  10. 【BZOJ 2252】 矩阵距离

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2252 [算法] 将所有是”1“的点入队,然后广度优先搜索,即可 [代码] #incl ...