版权声明:转载请附上地址 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;
}