AtCoder ARC 076D - Built?
传送门: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,则连接i和k的代价为|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?的更多相关文章
- 【题解】Atcoder ARC#90 F-Number of Digits
Atcoder刷不动的每日一题... 首先注意到一个事实:随着 \(l, r\) 的增大,\(f(r) - f(l)\) 会越来越小.考虑暴力处理出小数据的情况,我们可以发现对于左端点 \(f(l) ...
- AtCoder ARC 076E - Connected?
传送门:http://arc076.contest.atcoder.jp/tasks/arc076_c 平面上有一个R×C的网格,格点上可能写有数字1~N,每个数字出现两次.现在用一条曲线将一对相同的 ...
- AtCoder ARC 082E - ConvexScore
传送门:http://arc082.contest.atcoder.jp/tasks/arc082_c 本题是一个平面几何问题. 在平面直角坐标系中有一个n元点集U={Ai(xi,yi)|1≤i≤n} ...
- Atcoder ARC 082C/D
C - Together 传送门:http://arc082.contest.atcoder.jp/tasks/arc082_a 本题是一个数学问题. 有一个长度为n的自然数列a[1..n],对于每一 ...
- AtCoder ABC 076D - AtCoder Express
传送门:http://abc076.contest.atcoder.jp/tasks/abc076_d 本题是一个运动学问题——匀变速运动. 一个质点,从静止开始运动.按照速度限制,可将运动划分成n个 ...
- 【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)
题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: ...
- 【题解】Atcoder ARC#96 F-Sweet Alchemy
首先,我们发现每一个节点所选择的次数不好直接算,因为要求一个节点被选择的次数大于等于父亲被选择的次数,且又要小于等于父亲被选择的次数 \(+D\).既然如此,考虑一棵差分的树,规定每一个节点被选择的次 ...
- AtCoder ARC 090 E / AtCoder 3883: Avoiding Collision
题目传送门:ARC090E. 题意简述: 给定一张有 \(N\) 个点 \(M\) 条边的无向图.每条边有相应的边权,边权是正整数. 小 A 要从结点 \(S\) 走到结点 \(T\) ,而小 B 则 ...
- 【题解】Atcoder ARC#67 F-Yakiniku Restaurants
觉得我的解法好简单,好优美啊QAQ 首先想想暴力怎么办.暴力的话,我们就枚举左右端点,然后显然每张购物券都取最大的值.这样的复杂度是 \(O(n ^{2} m)\) 的.但是这样明显能够感觉到我们重复 ...
随机推荐
- 高阶MapReduce_1_链接多个MapReduce作业
链接MapReduce作业 1. 顺序链接MapReduce作业 顺序链接MapReduce作业就是将多个MapReduce作业作为生成的一个自己主动化运行序列,将上一个MapReduce作 ...
- 《从零開始学Swift》学习笔记(Day 52)——Cocoa错误处理模式
原创文章,欢迎转载. 转载请注明:关东升的博客 Swift错误处理模式,在Swift1.x和Swift 2.0是不同的两种模式. Swift 1.x代码错误处理模式採用Cocoa框架错误处理模式,到如 ...
- n阶导函数存在与n阶可导的区别
1.f(x)n阶导函数存在 <=======> f(n)(x)存在 指的是在某个区间内有定义 2.f(x)n阶可导根据题意可以有两种不同的解释: ①.题目中说的是在某点即在x=x0处n ...
- ⭐linux主次设备号介绍
1.主设备号与次设备号的功能 在Linux内核中,主设备号标识设备对应的驱动程序,告诉Linux内核使用哪一个驱动程序为该设备(也就是/dev下的设备文件)服务:而次设备号则用来标识具体且唯一的某个设 ...
- 2017 Multi-University Training Contest - Team 2 &&hdu 6053 TrickGCD
TrickGCD Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- Codeforces Round #402 D(二分)
D. String Game ...
- jFinal基于maven简单的demo
JFinal 是基于Java 语言的极速 web 开发框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ruby.py ...
- Vue页面间传值,以及客户端数据存储
初学Vue,遇到了页面传值的问题,大概网上学习了解了一下,在此跟大家分享一下学习心得,欢迎批评指正. 一.参数传值 如果是简单的页面传值,比如传一个id到详情页等等,推荐使用参数传值. 这里页面是通过 ...
- .htaccess的基本用法与介绍
●自定义错误页 .htaccess的一个应用是自定义错误页面,这将使你可以拥有自己的.个性化的错误页面(例如找不到文件时),而不是你的服务商提供的错误页或没有任何页面.这会让你的网站在出错的时候看上去 ...
- C#快速获取指定网页源码的几种方式,并通过字符串截取函数 或 正则 取指定内容(IP)
//只获取网页源码开始到标题位目的进行测试 //第一种方式经过测试,稍微快点 string url = "http://www.ip.cn"; HttpWebRequest req ...