10423: 强盗归来
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 27 Solved: 14
[ Submit][ Status][ Web Board]
Description
野猪岭的土匪坨子仇人九回来了,他灭了“虎啸堂”满门,不仅如此,他还要求n个村的村民在从一个村子到另一个村子的路上,强行向他们收取买路钱。为了反抗强盗的暴虐统治,村民们决定修筑地道,一起反抗强盗的暴虐统治。然而修筑地道所需的人力、财力、精力数值上与路程相等。现如今,良垣决定花尽可能少的人力、财力、精力,尽快地联络各地村民一同推翻强盗的暴虐统治。
这些村子编号为1-n,现在良垣事先知道这些村子的坐标,他的目的是修筑一定数量的地道,使得村子之间相互连通同时花费的人力、财力、精力尽可能的少。
现在呢,告诉你一个不幸的消息,你就是良垣,你没得选(造路是你唯一的选择)。给出你的答案
Input
有多组测试案例,
每一组第一行整数n(0 < n <= 100)表示村子的个数,接下来有n行,表示村子的坐标。第i+1行有两个实数xi,yi来表示第i个村子的坐标
Output
对于每一组测试案例,输出最少需要花费的人力、财力、精力(结果保留两位小数)
Sample Input
3
1.0 1.0
2.0 2.0
3.0 6.0
Sample Output
5.54
//好久没写最小生成树了,写这个题费了好长时间。
#include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #define INF 0x3f3f3f3f using namespace std; double map[110][110]; double dis[110]; int vis[110]; struct zz { double x; double y; }q[210]; double jl(zz a,zz b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int n; void prim() { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) dis[i]=map[1][i]; dis[1]=0; vis[1]=1; int i,j,k; double mm,sum=0.0; for(j=1;j<n;j++) { k=1;mm=INF; for(i=1;i<=n;i++) { if(!vis[i]&&dis[i]<mm) { k=i; mm=dis[i]; } } vis[k]=1; sum+=mm; for(i=1;i<=n;i++) { if(!vis[i]&&dis[i]>map[k][i]) dis[i]=map[k][i]; } } printf("%.2lf\n",sum); } int main() { int i,j; while(scanf("%d",&n)!=EOF) { memset(map,INF,sizeof(map)); for(i=1;i<=n;i++) scanf("%lf%lf",&q[i].x,&q[i].y); for(i=1;i<n;i++) { for(j=i+1;j<=n;j++) { map[i][j]=map[j][i]=jl(q[i],q[j]); } } prim(); } return 0; }