$P2212 [USACO14MAR]浇地Watering the Fields$

Posted qf-breeze

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了$P2212 [USACO14MAR]浇地Watering the Fields$相关的知识,希望对你有一定的参考价值。

(problem)

根据 两点之间距离
(dis = sqrt{(x1-x2)^2+(y1-y2)^2})
然后就是个最短生成树的模板
带一点贪心。

(N<=2000)
别被这个误导了。。
边数最多可能为((N*(N-1))/2)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL read() { LL x=0; register char c=getchar();  int f(1);
    while(!isdigit(c)) { if(c=='-') f=-1; c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+(c&15),c=getchar(); return x*f;
}
const int N = 2000 + 5 ;
int n,c;
struct P{
    int x; int y;
};
P a[N*N];
struct C{
    int x; int y; int Cos;
};
C f[N*N];
int fa[N];
int cnt(0);
int cost(0);
inline int Dis(int i,int j) {
    return pow(a[i].x-a[j].x,2)+pow(a[i].y-a[j].y,2);
}
inline int find(int x) {
    return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
}
inline bool cmp_ (C a,C b) {
    return a.Cos<b.Cos;
}
inline void kruskal() {
    sort(f+1,f+cnt+1,cmp_);
    int ans(0); 
    int num(0);
    for(register int i=1;i<=cnt;i++) {
        int fx=find(f[i].x),fy=find(f[i].y);
        if(fx==fy) continue ;
        fa[fx] = fy ; ans += f[i].Cos;
        if (++ num == n - 1) break ;
    }
    if(num == n-1) cout << ans << endl ;
    else puts("-1") ;
}
signed main() {
    n=read(); c=read();
    for(register int i=1;i<=n;i++) fa[i]=i;
    for(register int i=1;i<=n;i++) a[i].x=read(),a[i].y=read();
    for(register int i=1;i<=n;i++)
        for(register int j=i+1;j<=n;j++) {
            int k=Dis(i,j);
            if(k >= c) f[++cnt].Cos = k ,f[cnt].x = i , f[cnt].y = j ;
        }
    return kruskal() , 0 ;
}

以上是关于$P2212 [USACO14MAR]浇地Watering the Fields$的主要内容,如果未能解决你的问题,请参考以下文章

P2212 [USACO14MAR]浇地Watering the Fields

题解Luogu P2212 [USACO14MAR] 浇地 Watering the Fields 最小生成树

[USACO14MAR]浇地Watering the Fields

[USACO14MAR]浇地Watering the Fields

P2115 [USACO14MAR]Sabotage G(二分)

[USACO14MAR] Counting Friends