最小生成树 Building a Space Station 三维 作为范二青年我用了克鲁斯算法,而且很悲剧的是我很无奈的用g++交了一中午,然后WA= =。。。

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",&degree[i].x,&degree[i].y,&degree[i].z,&degree[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",&degree[i].x,&degree[i].y,&degree[i].z,&degree[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;
}
posted @ 2012-08-12 15:22  某某。  阅读(173)  评论(0编辑  收藏  举报