题意:在坐标纸上给出n个点,求最短距离连在一起。
思路:
1、求出所有点之间的距离(权值);
2、用编号代表坐标,剩下的就和普通的并查集一样了。
总结:难点使用编号代表坐标很难让人理解,并表示出来,但是耐心写一写,会成功的,写出来就明白了,反正我是这样的。
代码主要还是自己写。
参考代码:
#include<stdio.h> #include<math.h> #include<iostream> #include<algorithm> using namespace std; struct node { int start,end; double length; }point[5500]; double xx[102],yy[102]; int root[102]; int num[102]; int n; bool cmp(node a,node b) { return a.length<b.length; } int find_root(int son) { if(root[son]!=son) { root[son]=find_root(root[son]); } return root[son]; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { scanf("%lf%lf",&xx[i],&yy[i]); } int k=1; for(int i=1;i<n;i++) { for(int j=i+1;j<=n;j++) { point[k].length=sqrt((xx[i]-xx[j])*(xx[i]-xx[j])+(yy[i]-yy[j])*(yy[i]-yy[j])); point[k].start=i; point[k].end=j; k++; } } sort(point+1,point+k,cmp); // for(int i=1;i<k;i++) // { // printf("%d %d %.2lf\n",point[i].start,point[i].end,point[i].length); // } for(int i=1;i<=n;i++) { root[i]=i;num[i]=1; } double num1=0;int fx,fy; for(int i=1;i<k;i++) { fx=find_root(point[i].start); fy=find_root(point[i].end); if(fx!=fy) { root[fx]=fy; num[fy]+=num[fx]; num1+=point[i].length; } if(num[fx]>=n||num[fy]>=n) break; } printf("%.2lf\n",num1); } return 0; }