问题描述:
赤壁之战前夕,庞统向周瑜献连环计,瑜设计使蒋干邀庞统到曹营。操与统同观营寨,
又共论兵法。统对答如流使操敬服。统乘机提出:大江中风浪不息使北兵易生疾病。可将大
小船配搭,首尾用铁环连锁,铺阔板以便人马行走。操闻之大喜,派人连夜打造连环大钉,
锁住船只。
每打造一单位长度的铁索要花费一单位的钱,曹操希望用最少的花费将n 艘战船连接起
来(任意两艘战船直接或间接被铁索连接),每艘战船可以看成一个点,坐标为(xi,yi),曹
营中有一位神秘人物,他所在的战船必须和曹操所在战船直接连接,求最小花费。
数据输入:
第一行战船数n(2<=n<=100)。
第二行神秘人物所在的战船序号a,曹操所在战船序号b,(1<=a,b<=n,a!=b),战船序号
从1 到n。
接下来n 行,每行两个实数(建议定义成double 类型):xi,yi(-1000<=xi,yi<=1000),表
示序号为i 的战船的坐标。
结果输出:
连接n 艘战船的最小花费,输出答案的时候四舍五入保留两位小数。
输入示例: 输出示例:
4
2 3
0 0
1 0
0 -1
1 -1
3.14
根据prim算法思想,把已经建成的道路初始化为0就ok了
1 2 #include<stdio.h> 3 #include<string.h> 4 #include<cmath> 5 double g[101][101]; 6 double ans=0; 7 double func(double a,double b,double x,double y) 8 { 9 return fabs(sqrt((x-a)*(x-a)+(y-b)*(y-b))); 10 11 } 12 void prim(int n) 13 { 14 double lowcost[101],min;int closet[101]; 15 int i,j,k; 16 int used[101]; 17 memset(used,0,sizeof(used)); 18 for(i=1;i<=n;i++) 19 lowcost[i]=g[i][1], 20 closet[i]=1; 21 used[1]=1; 22 for(i=1;i<n;i++) 23 { 24 min=12345678; 25 j=1; 26 for(k=2;k<=n;k++) 27 { 28 if(lowcost[k]<min&&(!used[k])) 29 min=lowcost[k], 30 j=k; 31 } 32 used[j]=1; 33 ans+=g[j][closet[j]]; 34 for(k=2;k<=n;k++) 35 { 36 if(g[k][j]<=lowcost[k]&&(!used[k])) 37 { 38 lowcost[k]=g[k][j]; 39 closet[k]=j; 40 } 41 } 42 } 43 } 44 int main() 45 { 46 int n,i,j; 47 double t[110][2],a1,a2,m,tmp; 48 int a,b; 49 scanf("%d",&n); 50 scanf("%d %d",&a,&b); 51 int k=1; 52 for(i=1;i<=n;i++) 53 { 54 scanf("%lf %lf",&t[k][0],&t[k++][1]); 55 } 56 for(i=1;i<=n;i++) 57 for(j=1;j<=n;j++) 58 g[i][j]=12345678.0; 59 for(i=1;i<=n;i++) 60 { 61 for(j=1;j<=n;j++) 62 { 63 if(i!=j) 64 { 65 g[i][j]=func(t[i][0],t[i][1],t[j][0],t[j][1]); 66 } 67 else 68 g[i][j]=0; 69 } 70 } 71 double k1=func(t[a][0],t[a][1],t[b][0],t[b][1]); 72 g[a][b]=g[b][a]=0.0; 73 74 prim(n); 75 printf("%.2lf ",ans+k1); 76 return 0; 77 } 78 79