$P2872\ [USACO07DEC]道路建设Building\ Roads$

\(problem\)

错的原因是\(RE\)(大雾 , 时刻谨记 \(N\) 个地方的话 保守开 \(\frac{N^2}{2}\) 大小。 因为是边。
边最多的情况即完全图 : $1+2+3+4...+n = \frac{N*(N-1)}{2} $

所以还是个板子。

忽略丑陋的\(2^{18}\)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
inline LL read () { LL res = 0 ;int f (1) ;char ch = getchar ();
    while (!isdigit(ch)) { if (ch == '-') f = -1 ;ch = getchar();}
    while (isdigit(ch)) res = (res << 1) + (res << 3) + (ch ^ 48) ,ch = getchar(); return res * f ;
}
const int Maxn = 1<<20 ;
int n , m ;
int x[Maxn];
int y[Maxn];
int f[Maxn];
int cnt = 0 ;
int top = 0 ;
double ans = 0.0 ;
struct P{ int x,y; double val;};
P a[Maxn] ;
inline bool cmp_(P a,P b) {
    if(a.val==b.val) return a.x<b.x;
    return a.val<b.val;
}
inline int find ( int x ) { return x == f[x] ? f[x] : f[x] = find(f[x]) ; }
inline void merge( int x , int  y) {
    f[ find(x) ] = find (y) ;
}
inline void kruskal() {
    int count = 0 ;
    sort(a+1,a+cnt+1,cmp_) ;
    for(register int i=1;i<=cnt;i++) {
        count ++ ;
        if(find(a[count].x) != find(a[count].y)) ans += a[i].val , merge(a[i].x,a[i].y) ;
        //if(count == n-1) break ;
    }
    return ;
}
signed main () {
    n=read(); m=read();
    for(register int i=1;i<=n;i++) {
        x[i]=read(),y[i]=read();
    }
    for(register int i=1;i<=n;i++) {
        f[i]=i;
    }
    for(register int i=1; i<=n; i++)
        for(register int j=i+1; j<=n; j++) {
        	cnt ++ ;
            a[cnt].x=i; a[cnt].y=j;
            a[cnt].val=sqrt(pow((x[i]-x[j]),2)+pow((y[i]-y[j]),2));
        }
    for(register int i=1;i<=m;i++) {
        int A=read(),B=read();
        cnt ++ ;
        a[cnt].x = A ; a[cnt].y = B ; a[cnt].val = 0.0 ;
    }
    kruskal() ;
    printf("%.2lf\n",ans) ;
    return 0;
}
posted @ 2019-04-20 20:00  Isaunoya  阅读(124)  评论(0编辑  收藏  举报
TOP