我住包子山

this->blog.MoveTo("blog.baozishan.in")

zju1942解题报告

这道题我用了Kruscal+并查集算的
之前并查集用的不对,所以一直WA
并查集代码来自我的那本写数据结构与算法分析c++版 knuth的徒孙的网站

#include <cstdio>
#include 
<vector>
#include 
<cmath>
#include 
<algorithm>
using namespace std;

#ifndef DISJ_SETS_H
#define DISJ_SETS_H

// DisjSets class
//
// CONSTRUCTION: with int representing initial number of sets
//
// ******************PUBLIC OPERATIONS*********************
// void union( root1, root2 ) --> Merge two sets
// int find( x )              --> Return set containing x
// ******************ERRORS********************************
// No error checking is performed

#include 
<vector>
using namespace std;

/**
 * Disjoint set class.
 * Use union by rank and path compression.
 * Elements in the set are numbered starting at 0.
 
*/

class DisjSets
{
  
public:
    
explicit DisjSets( int numElements );

    
int find( int x ) const;
    
int find( int x );
    
void unionSets( int root1, int root2 );

  
private:
    vector
<int> s;
}
;

#endif


/**
 * Construct the disjoint sets object.
 * numElements is the initial number of disjoint sets.
 
*/

DisjSets::DisjSets( 
int numElements ) : s( numElements )
{
    
forint i = 0; i < s.size( ); i++ )
        s[ i ] 
= -1;
}


/**
 * Union two disjoint sets.
 * For simplicity, we assume root1 and root2 are distinct
 * and represent set names.
 * root1 is the root of set 1.
 * root2 is the root of set 2.
 
*/

void DisjSets::unionSets( int root1, int root2 )
{
//    if( s[ root2 ] < s[ root1 ] )  // root2 is deeper
        s[ root1 ] = root2;        // Make root2 new root
    
//else
    
//{
    
//    if( s[ root1 ] == s[ root2 ] )
    
//        s[ root1 ]--;          // Update height if same
    
//    s[ root2 ] = root1;        // Make root1 new root
    
//}
}



/**
 * Perform a find.
 * Error checks omitted again for simplicity.
 * Return the set containing x.
 
*/

int DisjSets::find( int x ) const
{
    
if( s[ x ] < 0 )
        
return x;
    
else
        
return find( s[ x ] );
}



/**
 * Perform a find with path compression.
 * Error checks omitted again for simplicity.
 * Return the set containing x.
 
*/

int DisjSets::find( int x )
{
    
if( s[ x ] < 0 )
        
return x;
    
else
        
return s[ x ] = find( s[ x ] );
}



struct Gedge
{
    
int startnumber;
    
int endnumber;
    
double weight;
    Gedge(
int s,int e,double w):startnumber(s),endnumber(e),weight(w){}
}
;
struct Gnode
{
    
int x;
    
int y;
    Gnode(
int xx,int yy):x(xx),y(yy){}
    Gnode():x(
0),y(0){}
    
static double dis(const Gnode & n1, const Gnode & n2)
    
{
        
double d1=(n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y);
        
return d1;
    }


}
;

bool comp(const Gedge& g1,const Gedge& g2)
{
    
return g1.weight<g2.weight;
}

vector
<Gedge> edgeV;
Gnode nodeArray[
201];
int main()
{
    
int n=0,cnt=1;
    
while(scanf("%d",&n)!=EOF)
    
{
        
if(n==0)break;
        
for(int i=0;i<n;i++)
        
{
            scanf(
"%d %d",&nodeArray[i].x,&nodeArray[i].y);
        }

        
for(int i=0;i<n-1;i++)
        
{
            
for(int j=i+1;j<n;j++)
            
{
                edgeV.push_back(Gedge(i,j,Gnode::dis(nodeArray[i],nodeArray[j])));
            }

        }

        DisjSets ds(n
+1);
        
double minstep=0;
        sort(edgeV.begin(),edgeV.end(),comp);
        
while(ds.find(0)!=ds.find(1))
        
{
            minstep
=edgeV[0].weight;
            
int a=ds.find(edgeV[0].startnumber);
            
int b=ds.find(edgeV[0].endnumber);
            
if(a!=b)
            
{
                ds.unionSets(a,b);               
            }

            edgeV.erase(edgeV.begin());
        }

        printf(
"Scenario #%d\nFrog Distance = %.3lf\n\n",cnt++,sqrt(minstep));
        edgeV.clear();
    }

}

posted on 2007-07-28 21:04 Gohan 阅读(427) 评论(0)  编辑 收藏 引用 所属分类: C++Practise


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