# bzoj1626 / 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 }
View Code

posted @ 2018-10-27 18:02  kafuuchino  阅读(88)  评论(0编辑  收藏  举报