• USACO22FEB Moo Network G


    洛谷P8191 [USACO22FEB] Moo Network G

    题目大意

    n n n个点,第 i i i个点的位置为 ( x i , y i ) (x_i,y_i) (xi,yi),其中 0 ≤ x i ≤ 1 0 6 , 0 ≤ y i ≤ 10 0\leq x_i\leq 10^6,0\leq y_i\leq 10 0xi106,0yi10。连接两个点 i , j i,j i,j的成本是 ( x i − x j ) 2 + ( y i − y j ) 2 (x_i-x_j)^2+(y_i-y_j)^2 (xixj)2+(yiyj)2,求能使这 n n n个点连通的最小成本。

    1 ≤ n ≤ 1 0 5 1\leq n\leq 10^5 1n105


    题解

    观察数据范围发现, y y y的范围不超过 10 10 10,而连最短的边显然更优,所以对于每个点,我们可以将其与距离其较近的点连边,然后在这些边中做 kruskal \text{kruskal} kruskal即可。

    先将点按横坐标从小到大排序,横坐标相同的按纵坐标排序,然后对于每个点,向左找 30 30 30个点连边,再在这些边中做 kruskal \text{kruskal} kruskal。因为 y y y的范围不超过 10 10 10,所以最小生成树中的边一般都在上面建的这些边中。

    时间复杂度为 O ( 30 n log ⁡ n ) O(30n\log n) O(30nlogn)

    code

    #include
    using namespace std;
    int n,v1=0,fa[100005];
    long long ans=0;
    struct node{
    	int x,y;
    }w[100005];
    struct line{
    	int x,y;
    	long long dis;
    }v[3000005];
    bool cmp1(node ax,node bx){
    	if(ax.x!=bx.x) return ax.x<bx.x;
    	return ax.y<bx.y;
    }
    bool cmp2(line ax,line bx){
    	return ax.dis<bx.dis;
    }
    long long dis(int i,int j){
    	return 1ll*(w[i].x-w[j].x)*(w[i].x-w[j].x)+1ll*(w[i].y-w[j].y)*(w[i].y-w[j].y);
    }
    int find(int ff){
    	if(fa[ff]!=ff) fa[ff]=find(fa[ff]);
    	return fa[ff];
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d%d",&w[i].x,&w[i].y);
    		fa[i]=i;
    	}
    	sort(w+1,w+n+1,cmp1);
    	for(int i=1;i<=n;i++){
    		for(int j=max(i-30,1);j<i;j++){
    			v[++v1]=(line){i,j,dis(i,j)};
    		}
    	}
    	sort(v+1,v+v1+1,cmp2);
    	for(int i=1;i<=v1;i++){
    		int r1=find(v[i].x),r2=find(v[i].y);
    		if(r1!=r2){
    			fa[r1]=r2;
    			ans+=v[i].dis;
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
  • 相关阅读:
    【算法系列】卡尔曼滤波算法
    如何提升和扩展 PostgreSQL — 从共享缓冲区到内存数据网格
    Java Web——JavaScript基础
    Mysql 索引
    js判断对象是否为空
    Java_多态/动态绑定机制/多态数组/多态参数
    函数指针+回调函数+点云鼠标点选和框选
    【深入理解设计模式】单例设计模式
    docker export、import、save、load 区别
    [附源码]计算机毕业设计云南美食管理系统Springboot程序
  • 原文地址:https://blog.csdn.net/tanjunming2020/article/details/132642106