Building a Space Station
题目连接:http://poj.org/problem?id=2031
没有什么难点,唯一要注意的是重复路径和相交的情况,但是前一点用克鲁斯基本可以无视~
今天涨姿势了~PKU上用G++输出时printf不能用lf得用f以前有个好习惯都用f。。。
View Code
加一个prim的写法
View Code
#include <stdio.h> #include <string.h> #include <math.h> #define maxn 1000000 struct node { double x,y,z,r; }degree[105]; double map[105][105]; double res(int i,int j) { double x,y,z; x = (degree[i].x-degree[j].x)*(degree[i].x-degree[j].x); y = (degree[i].y-degree[j].y)*(degree[i].y-degree[j].y); z = (degree[i].z-degree[j].z)*(degree[i].z-degree[j].z); double dis; dis = sqrt(x+y+z); if(dis > degree[i].r+degree[j].r) return dis-degree[i].r-degree[j].r; else return 0; } double prim(int n) { int vis[105] = {0}; double dis[105] = {0}; int i,j,pre; double min,ans; ans = 0; vis[1] = 1; for(i =2;i <= n;i++) dis[i] = map[1][i]; for(i = 2;i <= n;i++) { min = maxn; for(j =2;j <= n;j++)//寻找最短的那一条~ { if(!vis[j] && min > dis[j]) min = dis[j],pre = j; } vis[pre] = 1; ans += min; for(j = 2;j <= n;j++)//寻找下一个点,更新值 if(!vis[j] && dis[j] > map[pre][j]) dis[j] = map[pre][j]; } return ans; } int main() { int n,i,j; while(scanf("%d",&n)&&n) { for(i = 1;i <= n;i++) scanf("%lf %lf %lf %lf",°ree[i].x,°ree[i].y,°ree[i].z,°ree[i].r); for(i = 1;i <= n;i++) for(j = i+1;j <= n;j++) map[j][i] = map[i][j] = res(i,j); printf("%.3f\n",prim(n)); } }
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #define maxn 1000000 5 struct node 6 { 7 double x,y,z,r; 8 }degree[105]; 9 double map[105][105]; 10 11 double res(int i,int j) 12 { 13 double x,y,z; 14 x = (degree[i].x-degree[j].x)*(degree[i].x-degree[j].x); 15 y = (degree[i].y-degree[j].y)*(degree[i].y-degree[j].y); 16 z = (degree[i].z-degree[j].z)*(degree[i].z-degree[j].z); 17 double dis; 18 dis = sqrt(x+y+z); 19 if(dis > degree[i].r+degree[j].r) 20 return dis-degree[i].r-degree[j].r; 21 else 22 return 0; 23 } 24 double prim(int n) 25 { 26 int vis[105] = {0}; 27 double dis[105] = {0}; 28 29 int i,j,pre; 30 double min,ans; 31 32 ans = 0; 33 34 vis[1] = 1; 35 for(i =2;i <= n;i++) 36 dis[i] = map[1][i]; 37 38 for(i = 2;i <= n;i++) 39 { 40 min = maxn; 41 for(j =2;j <= n;j++) 42 { 43 if(!vis[j] && min > dis[j]) 44 min = dis[j],pre = j; 45 } 46 47 vis[pre] = 1; 48 ans += min; 49 50 for(j = 2;j <= n;j++) 51 if(!vis[j] && dis[j] > map[pre][j]) 52 dis[j] = map[pre][j]; 53 } 54 return ans; 55 } 56 int main() 57 { 58 int n,i,j; 59 while(scanf("%d",&n)&&n) 60 { 61 for(i = 1;i <= n;i++) 62 scanf("%lf %lf %lf %lf",°ree[i].x,°ree[i].y,°ree[i].z,°ree[i].r); 63 64 for(i = 1;i <= n;i++) 65 for(j = i+1;j <= n;j++) 66 map[j][i] = map[i][j] = res(i,j); 67 68 printf("%.3f\n",prim(n)); 69 } 70 }
#include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> struct degree { double x,y,z,r; }point[105]; struct node { int u,v; double w; }e[105*105]; int map[105][105]; int set[105]; int count,ncount; int cmp(const void *a,const void *b) { return (*(struct node *)a).w>(*(struct node *)b).w ? 1:-1; } void init(int n) { int i; for(i = 1;i <= n;i++) set[i] = i; return; } int find(int x) { if(x != set[x]) { set[x] = find(set[x]); } return set[x]; } void make_edge(int i, int j) { double dis; double x,y,z; x = (point[i].x-point[j].x)*(point[i].x-point[j].x); y = (point[i].y-point[j].y)*(point[i].y-point[j].y); z = (point[i].z-point[j].z)*(point[i].z-point[j].z); dis = sqrt(x+y+z); if(dis - point[i].r-point[j].r <= 0.000001) { e[count].u = i,e[count].v = j,e[count].w = 0; count++; return; } e[count].u = i,e[count].v = j,e[count].w = dis-point[i].r-point[j].r; count++; return; } int main() { int i,j,n; double ans; while(scanf("%d",&n)&&n) { ans = 0; init(n); for(i = 1;i <= n;i++) { scanf("%lf %lf %lf %lf",&point[i].x,&point[i].y,&point[i].z,&point[i].r); } count = 0; for(i = 1;i <= n;i++) { for(j = i+1;j <= n;j++) make_edge(i,j); } qsort(e,(n-1)*n/2,sizeof(e[0]),cmp); for(i = 0;i < (n-1)*n/2;i++) { int u,v; u = find(e[i].u); v = find(e[i].v); if(u != v) { set[u] = v; ans += e[i].w; } } printf("%.3lf\n",ans); } return 0; }