思路:一开始想用贪心来着,发现贪心有缺陷,然后就用了最小生成树来写,这里用了prime算法,首先,先建个图,两点之间的边的权值就是两个点的距离,然后直接prime模板
代码
#include<iostream> #include<algorithm> #include<cstring> #include<math.h> #include<cstdio> const int inf=0x7fffffff; using namespace std; struct node { double x; double y; }a[105]; int n; double Map[105][105]; double dist[105]; bool visit[105]; int flag; double prime(int x) { memset(visit,0,sizeof(visit)); flag=0; int temp=inf; double lowcast; double sum=0; for(int i=1;i<=n;i++) dist[i]=Map[x][i]; visit[x]=1; for(int i=1;i<=n-1;i++) { lowcast=inf; for(int j=1;j<=n;j++) { if(visit[j]==0&&dist[j]<lowcast) { temp=j;lowcast=dist[j]; } } if(temp==inf) { flag=1;break; } visit[temp]=1; sum+=lowcast; if(dist[temp]>1000) flag=1; for(int k=1;k<=n;k++) { if(visit[k]==0&&dist[k]>Map[temp][k]) dist[k]=Map[temp][k]; } } return sum; } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i==j) Map[i][j]=0; else Map[i][j]=inf; } } for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { Map[i][j]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); Map[j][i]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y)); if(Map[i][j]>1000||Map[i][j]<10) { Map[i][j]=inf; Map[j][i]=inf; } } } double x=prime(1); if(flag==1||x>=inf) printf("oh!\n"); else { x=x*100; printf("%.1lf\n",x); } } return 0; }