http://acm.hdu.edu.cn/showproblem.php?pid=1875
#include <bits/stdc++.h> using namespace std; #define N 109 #define INF 0x3f3f3f3f int i,j,n; double mmp[N][N]; bool vis[N];//标记是否已经放入最小生成树的那个集合里了 double dis[N];//记录不在已经加入最小生成树的这个集合里的元素到这个 集合的最小距离 int x[N],y[N]; double dist(int i,int j) { return sqrt(1.0*(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); } void input() { for(i=1; i<=n; ++i) scanf("%d%d",&x[i],&y[i]); for(i=1; i<=n; ++i) for(j=1; j<=n; ++j) { mmp[i][j]=dist(i,j); if(mmp[i][j]>1000||mmp[i][j]<10) { mmp[i][j]=INF; } } } void prim() { double sum=0; memset(vis,0,sizeof(vis)); int pos=1;//从1开始 for(i=1; i<=n; ++i) //第一次给low赋值 { dis[i]=mmp[1][i]; } vis[1]=1; //已经找到一个点1,再找n-1个 for(i=1; i<n; ++i) { double minn=INF; for(j=1; j<=n; ++j) { if(!vis[j]&&minn>dis[j])//找下一个点到这个集合的最小值 { minn=dis[j];//记下这个最小值 pos=j;//记下这个点 } } if(minn==INF) { printf("oh!\n"); return ; } sum+=minn; vis[pos]=1;//把刚刚找到的这个点加入集合 for(j=1; j<=n; ++j) //更新low数组 { if(!vis[j]&&dis[j]>mmp[pos][j]) { dis[j]=mmp[pos][j]; } } } printf("%.1lf\n",sum*100); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); input(); prim(); } return 0; }