标签:
3 1.0 1.0 2.0 2.0 2.0 4.0
3.41
题意:给你几个点(二维),求将它们连接起来的最小线段的长度。
思路:由于输入的只是点的坐标,所以要先求出它们两两之间的距离。然后就没有然后了。
#include <cstdio> #include <cmath> #include <iostream> using namespace std; const int INF=0x3f3f3f3f; struct node { double x,y; } t[105]; double dis[105]; double a[105][105]; bool vis[105]; int n; double Prime() { for(int i=0;i<n;i++) { dis[i]=a[0][i]; vis[i]=false; } dis[0]=0; vis[0]=true; double ans=0; for(int i=1;i<n;i++) { int p=-1; double minn=INF; for(int j=0;j<n;j++) { if(!vis[j]&&dis[j]<minn) minn=dis[p=j]; } ans+=minn; vis[p]=true; for(int j=0;j<n;j++) { if(!vis[j]&&dis[j]>a[p][j]) dis[j]=a[p][j]; } } return ans; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=0; i<n; i++) scanf("%lf%lf",&t[i].x,&t[i].y); for(int i=0; i<n; i++) { for(int j=0; j<n; j++) if(i==j) a[i][j]=0.0; else a[i][j]=sqrt((t[i].x-t[j].x)*(t[i].x-t[j].x)+(t[i].y-t[j].y)*(t[i].y-t[j].y)); } printf("%.2lf\n",Prime()); } return 0; }
#include <cstdio> #include <algorithm> #include <cmath> using namespace std; const int INF=0x3f3f3f3f; struct Point { double x,y; }t[100]; struct node { int s,e; double w; }a[5000+5]; int fa[105]; int n,m; int Find(int x) { if(x==fa[x]) return x; return fa[x]=Find(fa[x]); } bool cmp(node a,node b) { return a.w<b.w; } double Kruskal() { for(int i=0;i<n;i++) fa[i]=i; sort(a,a+m,cmp); double ans=0; for(int i=0;i<m;i++) { int fx=Find(a[i].s); int fy=Find(a[i].e); if(fx!=fy) { ans+=a[i].w; fa[fx]=fy; } } return ans; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) scanf("%lf%lf",&t[i].x,&t[i].y); m=0; for(int i=0;i<n;i++) { for(int j=0;j<i;j++) { a[m].s=i; a[m].e=j; a[m++].w=sqrt((t[i].x-t[j].x)*(t[i].x-t[j].x)+(t[i].y-t[j].y)*(t[i].y-t[j].y)); } } printf("%.2lf\n",Kruskal()); } return 0; }
HDU 1162 Eddy's picture【最小生成树,Prime算法+Kruskal算法】
标签:
原文地址:http://blog.csdn.net/hurmishine/article/details/52122676