题目描述
There are N towns on a plane. The i-th town is located at the coordinates (xi,yi). There may be more than one town at the same coordinates.
You can build a road between two towns at coordinates (a,b) and (c,d) for a cost of min(|a−c|,|b−d|) yen (the currency of Japan). It is not possible to build other types of roads.
Your objective is to build roads so that it will be possible to travel between every pair of towns by traversing roads. At least how much money is necessary to achieve this?
Constraints
2≤N≤105
0≤xi,yi≤109
All input values are integers.
输入
Input is given from Standard Input in the following format:
N
x1 y1
x2 y2
:
xN yN
输出
Print the minimum necessary amount of money in order to build roads so that it will be possible to travel between every pair of towns by traversing roads.
样例输入
3 1 5 3 9 7 8
样例输出
3
提示
Build a road between Towns 1 and 2, and another between Towns 2 and 3. The total cost is 2+1=3 yen.
来源/分类
题意:
给n个点,可以在任意两点之间修建道路,花费为min( |x1-x2| , |y1-y2| ),问最少花费多少可以连通任意两点。
分析:
很明显的最小生成树问题,令人窒息的建图操作。
建图的话先对x排序相邻两点建条边,在对y排序相邻两点在建一条边,然后直接用Kruscal算法求最小生成树。
表示自己蒻的一批,膜拜dalao。
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <utility>
#include <time.h>
#include <set>
#include <bitset>
#include <vector>
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
#define ms(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;}
ll qpow1(ll a, ll b){ll s=1;while(b>0){if(b&1)s=s*a;a=a*a;b=b>>1;}return s;}
// a^b;
//mod x^y:
ll qpow(ll x, ll y, ll mod){ll s=1;while(y){if(y&1)s=s*x%mod;x=x*x%mod;y>>=1;}return s;}
const int maxn=1e5+5;
const int mod=1e9+7;
int fa[maxn];
struct Node{
ll x, y, id;
}no[maxn];
struct Edge{
ll v, u, w;
}ed[maxn<<1];
int cmp1(Node a, Node b){return a.x<b.x;}
int cmp2(Node a, Node b){return a.y<b.y;}
int cmp3(Edge a, Edge b){return a.v<b.v;}
int Find(int x){
if(fa[x]==x) return fa[x];
return fa[x]= Find(fa[x]);
}
int main()
{
int n, cnt=1; scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld", &no[i].x, &no[i].y);
no[i].id=i; fa[i]=i;
}
sort(no+1, no+1+n, cmp1);
for(int i=2;i<=n;i++){
ed[cnt].u=no[i-1].id;
ed[cnt].w=no[i].id;
ed[cnt++].v=no[i].x-no[i-1].x;
}
sort(no+1, no+1+n, cmp2);
for(int i=2; i<=n; i++){
ed[cnt].u=no[i-1].id;
ed[cnt].w=no[i].id;
ed[cnt++].v=no[i].y-no[i-1].y;
}
sort(ed+1, ed+1+cnt, cmp3);
ll ans=0; int cot=0;
for(int i=1;i<=cnt;i++){
int fa_u=Find(ed[i].u);
int fa_w=Find(ed[i].w);
if(fa_u!=fa_w)
{
fa[fa_u]=fa_w;
cot++; ans+=ed[i].v;
}
if(cot==n-1) break;
}
printf("%lld\n",ans);
return 0;
}