[USACO14MAR]浇地Watering the Fields--Kruskal

版权声明:转载请附上地址 https://blog.csdn.net/weixin_44574520/article/details/87627482

[USACO14MAR]浇地Watering the Fields

洛谷
在这里插入图片描述
在这里插入图片描述

题目分析:

  • 一道最小生成树题
  • 读入每个点的坐标后,预处理出每两点之间的边,存进结构体中(注意避免不要建重边,不然TLE)
  • 边权值小于c不能选择加入最小生成树中

Code:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 2010
#define maxm 4000100

int f[maxn],size=0,n,x[maxn],y[maxn],vis[maxn][maxn];
ll c;
struct node{
	int u,v;
	ll w;
}e[maxm];

inline ll read1_(){
	ll x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

inline int read_(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9'){
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}

inline bool cmp_(node aa,node bb){
	return aa.w<bb.w;
}

inline int find_(int x){
	if(f[x]==x) return x;
	else return f[x]=find_(f[x]);
}

inline void merge_(int x,int y){
	int rx=find_(x);
	int ry=find_(y);
	f[rx]=ry;
}

inline void ksul_(){
	int k=0;ll ans=0;
	for(int i=1;i<=size;i++){
		if(find_(e[i].u)!=find_(e[i].v)){
			if(e[i].w>=c){
			  ans+=e[i].w;
			  merge_(e[i].u,e[i].v);
			  k++;				
			}
		}
		if(k==(n-1)){
			printf("%lld",ans);
			exit(0);
		}
	}
	if(k<(n-1)) printf("-1");
}

inline void clean_(){
	for(int i=0;i<2005;i++) f[i]=i;
	memset(vis,0,sizeof(vis));
}

inline void init_(){
	freopen("gjiaos.txt","r",stdin);
}

inline void readda_(){
	clean_();
	n=read_();c=read1_();
	for(int i=1;i<=n;i++){
		x[i]=read_();y[i]=read_();
	}
}

inline void work_(){
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) continue;
			if(vis[i][j]) continue;
			size++;
			e[size].u=i;
			e[size].v=j; 
			e[size].w=((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
			vis[i][j]=1;vis[j][i]=1;		
		}
	}
	sort(e+1,e+size+1,cmp_);
	ksul_();
}

int main(){
	init_();
	readda_();
	work_();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44574520/article/details/87627482