zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    java web设置全局context参数
    tomcat ider配置
    JDBC Druid式link
    JDBC c3p0
    JDBCUtils 工具类
    顺序栈
    线性表链式存储结构的实现的使用
    线性表顺序存储结构的实现和运用
    Mat类下的data指针的深刻理解
    Mat类下几个属性的理解
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10319151.html
Copyright © 2011-2022 走看看