HDU-1162-Eddy's picture
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1162
题意:
最小生成树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<cmath> 4 using namespace std; 5 6 const int maxn = 100+10; 7 int far[maxn]; 8 int n, m; 9 int k; 10 struct Edge 11 { 12 const bool operator<(Edge &n)const 13 { 14 return value<n.value; 15 } 16 int start; 17 int end; 18 double value; 19 }edge[maxn*maxn]; 20 21 bool cmp(struct Edge &a, struct Edge &b) 22 { 23 return a.value<b.value; 24 } 25 26 void init() 27 { 28 int i, j; 29 for(i=0; i<=n; i++) 30 far[i] = i; 31 } 32 33 int find(int a) 34 { 35 if(far[a]!=a) 36 far[a] = find(far[a]); 37 return far[a]; 38 } 39 40 void Union(int a, int b) 41 { 42 a = find(a); 43 b = find(b); 44 if(a != b) 45 far[a] = b; 46 } 47 48 double kruskal() 49 { 50 init(); 51 sort(edge,edge+n*(n-1)+1,cmp); 52 double sum = 0; 53 int count = 0; 54 for(int i=1; i<=n*(n-1) && count<n; i++) 55 { 56 int a=edge[i].start; 57 int b=edge[i].end; 58 if(find(a)!=find(b)) 59 { 60 Union(a, b); 61 sum+=edge[i].value; 62 count++; 63 } 64 } 65 return sum; 66 } 67 68 int main() 69 { 70 double a[maxn], b[maxn]; 71 while(cin>>n) 72 { 73 //m = n*(n-1)/2; 74 75 for(int i=1; i<=n; i++) 76 { 77 scanf("%lf%lf",&a[i], &b[i]); //因为是无向图,所以要两次赋值 78 } 79 k=1; 80 double c; 81 for(int i=1; i<n; i++) 82 { 83 for(int j=i+1; j<=n; j++) 84 { 85 //if(i != j) 86 //{ 87 c = sqrt((a[i]-a[j])*(a[i]-a[j])+(b[i]-b[j])*(b[i]-b[j])); 88 edge[k].start = i; 89 edge[k].end = j; 90 edge[k++].value = c; 91 edge[k].start = j; 92 edge[k].end = i; 93 edge[k++].value = c; 94 //} 95 } 96 } 97 printf("%.2lf\n", kruskal()); 98 } 99 return 0; 100 }