bzoj1626 / P2872 [USACO07DEC]道路建设Building Roads
P2872 [USACO07DEC]道路建设Building Roads
kruskal求最小生成树。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<queue> 6 #include<algorithm> 7 #define re register 8 using namespace std; 9 typedef double ld; 10 typedef long long ll; 11 ll sqr(ll a){return a*a;} 12 #define N 1002 13 struct node{ll x,y;}a[N]; 14 struct edge{ 15 int f,t; ld dis; 16 edge(){} 17 edge(int A,int B,ld C): 18 f(A),t(B),dis(C) 19 {} 20 bool operator < (const edge &tmp) const{return dis<tmp.dis;} 21 }b[N*N]; 22 int n,m,tp,fa[N],k; ld ans; 23 ld dist(node A,node B){return sqrt((ld)(sqr(A.x-B.x)+sqr(A.y-B.y)));} 24 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 25 void uni(int x,int y){ 26 int r1=find(x),r2=find(y); 27 if(r1!=r2) fa[r2]=r1; 28 } 29 int main(){ 30 scanf("%d%d",&n,&m); int q1,q2; 31 for(re int i=1;i<=n;++i){ 32 scanf("%lld%lld",&a[i].x,&a[i].y); fa[i]=i; 33 for(re int j=1;j<i;++j) b[++tp]=edge(j,i,dist(a[j],a[i]));//把可能的边存起来 34 }sort(b+1,b+tp+1); 35 for(re int i=1;i<=m;++i){ 36 scanf("%d%d",&q1,&q2); 37 if(find(q1)!=find(q2)) ++k,uni(q1,q2); 38 } 39 for(re int i=1;i<=tp&&k<n-1;++i) 40 if(find(b[i].f)!=find(b[i].t)){ 41 uni(b[i].f,b[i].t); 42 ans+=b[i].dis; ++k; 43 } 44 printf("%.2lf",ans); 45 return 0; 46 }