HDU 3405 World Islands (prim算法)

来源:互联网 发布:旅游网络销售范围 编辑:程序博客网 时间:2024/06/08 17:24

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3405


【题目大意】

给你n个点的坐标,忽视其中一个点,求余下点的最小生成树。

我们不知道忽视的是哪一个点,所以要进行n次最小生成树。

prim算法需要使用一个标记数组 intree ,我们只要把忽视的那个点放入intree就不会扫描了;


【源代码】

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;const int maxn = 55;struct node{int x,y;}PP[maxn];const double INF = 100000000.0;double G[maxn][maxn];bool intree[maxn];double minDist[maxn];int n;double distane(node a,node b){return sqrt((double)(a.x-b.x)*(a.x-b.x)+(double)(a.y-b.y)*(a.y-b.y));}double prim(int x){double sum=0;intree[x]=1;if(x!=0){//如果忽视的点不是 0 for(int i=0;i<n;i++){ //起点置为 0 minDist[i]=G[i][0];}intree[0]=1; }else{  //否则for(int i=0;i<n;i++){ //起点置为1minDist[i]=G[i][1];}intree[1]=1;}for(int nodeNum=1;nodeNum<n-1;nodeNum++){ //注意这里要找的点只有n-2个点double tmpMin=INF;int addNode=-1;for(int i=0;i<n;i++){if(!intree[i]&&minDist[i]<tmpMin){ tmpMin = minDist[i];addNode = i;}}if(tmpMin==INF) { return -1;}sum+=tmpMin;intree[addNode]=1;for(int i=0;i<n;i++){if(!intree[i]&&G[addNode][i]<minDist[i])minDist[i]=G[addNode][i];}}if(sum!=0)return sum;return -1;}void init(){for(int i=0;i<maxn;i++)for(int j=0;j<maxn;j++)G[i][j]=INF;}int main(){int T;scanf("%d",&T);while(T--){init();scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d%d",&PP[i].x,&PP[i].y);}for(int i=0;i<n;i++){for(int j=i+1;j<n;j++){double dis = distane(PP[i],PP[j]);G[i][j]=min(G[i][j],dis);G[j][i]=min(G[j][i],dis);}}double ans=INF;for(int i=0;i<n;i++){memset(intree,0,sizeof(intree));for(int j=0;j<maxn;j++)minDist[j]=INF; //这里要初始化double tmp = prim(i);if(tmp!=-1)ans=min(tmp,ans);}printf("%.2lf\n",ans);}return 0;}


0 0