传送门: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. IntelliJ IDEA 问题总结之二(待补充) —— 快捷键、主题样式、导出jar、sqlite

    随着对idea的使用,问题越来越多,開始第二篇问题总结. 1.快捷键. 用惯了eclipse再用idea后,快捷键就是一个大问题. 并且网上idea的快捷键有非常多版本号.不知道是不是老版本号和新版本 ...

  2. 系统服务-----Activity服务的获取getSystemService

    android的后台存在非常多service,它们在系统启动的时候被SystemServer开启.来为系统的正常执行做支撑.Activity中要调用这些service就得使用getSystemServ ...

  3. T4语法

    阅读目录   阅读目录 1.什么是T4? 2.vs插件的安装 3.T4初体验 4.T4语法 其实对于“T4模板”的学习,讲得最详细的还是MSDN,下面给出对应的链接,可以点开深入的了解. 回到顶部 1 ...

  4. HDU5526/BestCoder Round #61 (div.1)1004 Lie 背包DP

    Lie   问题描述 一个年级总共有N个学生,每个人属于唯一一个班级.现在他们站在一排,同班同学并不一定会站在一起,但每个人都会说一句话:“站在我左边的有Ai个同班同学,右边有Bi个同班同学”.然而并 ...

  5. kafka备份机制——zk选举leader,leader在broker里负责备份

    Kafka架构 如上图所示,一个典型的kafka集群中包含若干producer(可以是web前端产生的page view,或者是服务器日志,系统CPU.memory等),若干broker(Kafka支 ...

  6. Java 错误:找不到或无法加载主类(源文件中含有包名 package)

    1. 问题定位 编译(javac)和执行(java)java 程序时,出现这种类型的错误:找不到或无法加载主类: 首先排除是否是环境变量配置不当造成的问题,只要保证,命令行界面能够识别 javac/j ...

  7. B1934 [Shoi2007]Vote 善意的投票 最小割

    一开始不太会,结果看完题解就是一个建图的网络流.然后就结了. 题干: 题目描述 幼儿园里有n个小朋友打算通过投票来决定睡不睡午觉.对他们来说,这个问题并不是很重要,于是他们决定发扬谦让精神.虽然每个人 ...

  8. bzoj1895

    fhqtreap 其实fhqtreap只有可持久化之后才用新建节点... reverse和splay一样. //#include<bits/stdc++.h> #include<cs ...

  9. NSURLSession 和 NSURLConnection 的比较

    一.NSURLConnection 1.iOS2.0出现,iOS9.0后废弃的网络请求发送方式 2.可以在初始化时确定发送同步还是异步的请求,并且可以选择执行队列. +(void)sendAsynch ...

  10. BZOJ 3679 数位DP

    思路: f[i][j]表示i位数乘积为j的方案数 j的取值最多5000多种,那就开个map存一下好了 f[i][mp[k*rec[j]]]+=f[i-1][j]; //By SiriusRen #in ...