zoukankan      html  css  js  c++  java
  • [USACO14MAR]Watering the Fields S

    欧几里得距离不需要开根号,题目描述联通的最小代价指的是和。

    细节:
    1.因为克鲁斯卡尔算法枚举的是边,所以不需要在意是无向图,仅存一遍即可,即32、33行,j直接从i+1开始枚举。
    2.最后判断时,如果tot==n-1,让其break,再外面再进行其他操作会更快一些。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2005;
    int n,c,tot,cnt,ans;
    struct node{
    	int x,y;
    }a[N];
    int f[N];
    struct Node{
    	int x,y;
    	int w;
    }edge[N*N];
    bool cmp(Node a,Node b){
    	return a.w<b.w;
    }
    int find(int x){
    	if(x==f[x]) return x;
    	return f[x]=find(f[x]);
    }
    int main(){
    	scanf("%d%d",&n,&c);
    	for(int i=1;i<=n;i++){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		a[i].x=u; a[i].y=v;
    	}
    	for(int i=1;i<=n;i++) f[i]=i;
    	for(int i=1;i<=n;i++)
    	for(int j=i+1;j<=n;j++){
    		int tmp=(a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);
    		if(tmp>=c){
    			edge[++cnt].x=i; edge[cnt].y=j; edge[cnt].w=tmp;
    		}
    	}
    	sort(edge+1,edge+cnt+1,cmp);
    	for(int i=1;i<=cnt;i++){
    		int r1=find(edge[i].x);
    		int r2=find(edge[i].y);
    		if(r1==r2) continue;
    		f[r1]=r2;
    		tot++;
    		ans+=edge[i].w;
    		if(tot==n-1) break;
    	}
    	if(tot==n-1){
    		printf("%d",ans);
    	}
    	else printf("-1");
    	return 0;
    }
    
  • 相关阅读:
    如何理解联合文件系统?
    Docker 学习笔记(一)
    Bzoj 3124: [Sdoi2013]直径 题解
    Bzoj 3131 [Sdoi2013]淘金 题解
    欧拉路(题目)
    硬币问题
    线段树、树状数组
    Splay树、Treap树
    模拟退火
    广搜题目(一本通)
  • 原文地址:https://www.cnblogs.com/New-ljx/p/14801212.html
Copyright © 2011-2022 走看看