随笔-38  评论-23  文章-0  trackbacks-0

刚拿到题目,就想到将集合看成一个独立点,求次MST。再对每个集合内的所有点求MST..

可惜比赛的时候没过这题。。错误原来在 空的集合 是不需要连接(这个没考虑所以出错了)
我用了prim算法 没什么优化..903ms过的.(可以用堆优化下)
#include<iostream>
#include
<cmath>
using namespace std;
const double inf= 1000000000;
double math[105][105],matx[105][105];
struct point
{
    
double x,y,z;
}
;
point hy[
105][105];
int num[105],coll[105];
bool eq(point e,point d)
{
    
if(abs(e.x-d.x)<1e-6&&abs(e.y-d.y)<1e-6&&abs(e.z-d.z)<1e-6)
        
return true;
    
return false;
}

double prim(double mat[][105],int n)
{
    
double dist[105];
    
bool visit[105];
    
for(int i=0;i<n;i++)
        dist[i]
=inf;
    memset(visit,
false,sizeof(visit));
    dist[
0]=0;
    
double sum=0;
    
for(int i=0;i<n;i++)
    
{
        
int minpos=-1;double minv=inf;
        
for(int j=0;j<n;j++)
        
{
            
if(!visit[j]&&(minpos==-1||dist[j]<minv))
            
{
                minpos
=j;
                minv
=dist[j];
            }

        }

        visit[minpos]
=true;
        sum
+=dist[minpos];
        
for(int j=0;j<n;j++)
        
{
            
if(!visit[j]&&dist[j]>mat[minpos][j])
                dist[j]
=mat[minpos][j];
        }

    }

    
return sum;
}

int main()
{
    
int n,m;
    
while(cin>>n)
    
{
        cin
>>m;
        memset(num,
0,sizeof(num));
        
for(int i=0;i<m;i++)
        
{
            point d;
            
int id,j;
            cin
>>d.x>>d.y>>d.z>>id;
            
for(j=0;j<num[id-1];j++)
            
{
                
if(eq(hy[id-1][j],d)) break;
            }

            
if(j==num[id-1])
            
{
                hy[id
-1][num[id-1]]=d;
                num[id
-1]++;
            }

        }

        memset(math,
0,sizeof(math));
        
int len=0;
        
for(int i=0;i<n;i++)
            
if(num[i]!=0)
                coll[len
++]=i;
        
for(int i=0;i<len;i++)
            
for(int j=0;j<len;j++)
                
{
                    
if(i==j)
                    
{
                        math[i][j]
=0;
                        
continue;
                    }

                    math[i][j]
=abs((double)(num[coll[i]]-num[coll[j]]))*abs((double)(coll[i]-coll[j]));
                }

        
double sum=0;
        sum
+=prim(math,len);
        
for(int i=0;i<n;i++)
        
{
            point it,it2;
            
int l1,l2;
            memset(matx,
0,sizeof(matx));
            
for(l1=0;l1<num[i];l1++)
            
{
                
for(l2=0;l2<num[i];l2++)
                
{
                    
if(l1==l2)
                    
{
                        matx[l1][l2]
=0;
                        
continue;
                    }

                    it
=hy[i][l1];
                    it2
=hy[i][l2];
                    
double l=(it.x-it2.x)*(it.x-it2.x)+(it.y-it2.y)*(it.y-it2.y)+(it.z-it2.z)*(it.z-it2.z);
                    matx[l1][l2]
=sqrt(l);
                }

            }

            
double v=prim(matx,num[i]);
            sum
+=v;
        }

        printf(
"%.4lf\n",sum);
    }

    
return 0;
}

posted on 2009-05-02 20:37 米游 阅读(346) 评论(0)  编辑 收藏 引用 所属分类: ACM

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理