Atcoder 076D

链接:http://arc076.contest.atcoder.jp/tasks/arc076_b

题目大意:给定平面上n个点,任意两点距离定义为 min(|a−c|,|b−d|), 求最小生成树。

分析:可以用类似曼哈顿距离最小生成树的方法,如在y轴顺时针偏45°的区域,取x最小的点,其它区域类似。这么做有点复杂。。区域内的最小点不好求。。

考虑x坐标,每个点只可能和x值相邻的点连,因此可以分别对x y排序,边只取相邻的点,然后再求一下最小生成树。复杂度为O(nlogn)。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<vector>
 4 using namespace std;
 5 struct Pair{
 6     int x,y;
 7 }p[100005];
 8 struct edge{
 9     int s,t,cost;
10 }e[2][100005];
11 int s[100005],t[100005],fa[100005];
12 int Find(int x){return x==fa[x]?x:fa[x]=Find(fa[x]);}
13 bool Cmpx(int a,int b){
14     return p[a].x<p[b].x;
15 }
16 bool Cmpy(int a,int b){
17     return p[a].y<p[b].y;
18 }
19 bool Cmpe(edge a,edge b){
20     return a.cost<b.cost;
21 }
22 int main(){
23     int n;
24     cin>>n;
25     for(int i=0;i<n;i++){
26         cin>>p[i].x>>p[i].y;
27         fa[i]=i;
28         s[i]=i;t[i]=i;
29     }
30     sort(s,s+n,Cmpx);
31     sort(t,t+n,Cmpy);
32     for(int i=0;i<n-1;i++){
33         e[0][i].s=s[i+1];
34         e[0][i].t=s[i];
35         e[0][i].cost=p[s[i+1]].x-p[s[i]].x;
36     }
37     for(int i=0;i<n-1;i++){
38         e[1][i].s=t[i+1];
39         e[1][i].t=t[i];
40         e[1][i].cost=p[t[i+1]].y-p[t[i]].y;
41     }
42     sort(e[0],e[0]+n-1,Cmpe);
43     sort(e[1],e[1]+n-1,Cmpe);
44     int i=0,j=0,count=0;
45     long long cost=0;
46     while(count<n-1){
47         if(i<=n-1&&e[0][i].cost<=e[1][j].cost){
48             int x=Find(e[0][i].s),y=Find(e[0][i].t);
49             fa[x]=y;
50             cost+=e[0][i].cost;
51         }else{
52             int x=Find(e[1][j].s),y=Find(e[1][j].t);
53             fa[x]=y;
54             cost+=e[1][j].cost;
55         }
56         count++;
57         while(i<n-1&&Find(e[0][i].s)==Find(e[0][i].t))i++;
58         while(j<n-1&&Find(e[1][j].s)==Find(e[1][j].t))j++;
59     }
60     cout<<cost<<endl;
61     return 0;
62 }
原文地址:https://www.cnblogs.com/7391-KID/p/7080318.html