atcoder 2643 切比雪夫最小生成树

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(|ac|,|bd|) 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
  • 2N105
  • 0xi,yi109
  • All input values are integers.
Input

Input is given from Standard Input in the following format:

N
x1 y1
x2 y2
:
xN yN
Output

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.

Sample Input 1
3
1 5
3 9
7 8
Sample Output 1
3

Build a road between Towns 1 and 2, and another between Towns 2 and 3. The total cost is 2+1=3 yen.

Sample Input 2
6
8 3
4 9
12 19
18 1
13 5
7 6
Sample Output 2
8


两点之间的距离定义min( |a-b|,|c-d| ),就是切比雪夫距离;
我们要求这样的定义下的最小生成树;
考虑Kruskal算法:每次选取距离最小的边加入其中且保证不能出现环;
那么我们分别按照x,y进行排序;
最后再统一排序即可;
此时进行普通的Kruskal即可;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#include<cctype>
//#pragma GCC optimize(2)
using namespace std;
#define maxn 2000005
#define inf 0x7fffffff
//#define INF 1e18
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
#define rdult(x) scanf("%lu",&x)
#define rdlf(x) scanf("%lf",&x)
#define rdstr(x) scanf("%s",x)
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 1000000000
#define sq(x) (x)*(x)
#define eps 1e-4
typedef pair<int, int> pii;
#define pi acos(-1.0)
//const int N = 1005;
#define REP(i,n) for(int i=0;i<(n);i++)
typedef pair<int, int> pii;
inline ll rd() {
	ll x = 0;
	char c = getchar();
	bool f = false;
	while (!isdigit(c)) {
		if (c == '-') f = true;
		c = getchar();
	}
	while (isdigit(c)) {
		x = (x << 1) + (x << 3) + (c ^ 48);
		c = getchar();
	}
	return f ? -x : x;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}
int sqr(int x) { return x * x; }


/*ll ans;
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if (!b) {
		x = 1; y = 0; return a;
	}
	ans = exgcd(b, a%b, x, y);
	ll t = x; x = y; y = t - a / b * y;
	return ans;
}
*/


int n;
int tot;
struct node {
	int x, y;
	int d;
	node(){}
	node(int x,int y,int d):x(x),y(y),d(d){}

}nd[maxn],nd2[maxn];

bool cmp(node a, node b) {
	return a.x < b.x;
}
bool cmp2(node a, node b) {
	return a.y < b.y;
}

bool cmp3(node a, node b) {
	return a.d < b.d;
}

int fa[maxn];
void init() {
	for (int i = 0; i <= n; i++)fa[i] = i;
}
int findfa(int x) {
	if (x == fa[x])return x;
	return fa[x] = findfa(fa[x]);
}

void merge(int u, int v) {
	int p = findfa(u);
	int q = findfa(v);
	if (p != q) {
		fa[p] = q;
	}
}

bool chk(int x, int y) {
	if (findfa(x) == findfa(y))return true;
	else return false;
}

int kruskal() {
	int sum = 0;
	init();
	for (int i = 0; i < tot; i++) {
		node tmp = nd2[i];
		if (tmp.d == 0)merge(tmp.x, tmp.y);
		if (!chk(tmp.x, tmp.y)) {
			merge(tmp.x, tmp.y); sum += tmp.d;
		}
	}
	return sum;
}

int main() {
//	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		rdint(nd[i].x); rdint(nd[i].y);
		nd[i].d = i;
	}
	tot = 0;
	sort(nd + 1, nd + 1 + n, cmp);
	for (int i = 2; i <= n; i++) {
		nd2[tot++] = node(nd[i].d, nd[i - 1].d, nd[i].x - nd[i - 1].x);
	}
	sort(nd+1, nd + n+1, cmp2);
	for (int i = 2; i <= n; i++) {
		nd2[tot++] = node(nd[i].d, nd[i - 1].d, nd[i].y - nd[i - 1].y);
	}
	sort(nd2, nd2 + tot, cmp3);
	int sum = kruskal();
	cout << sum << endl;
	return 0;
}

EPFL - Fighting
原文地址:https://www.cnblogs.com/zxyqzy/p/10319151.html