HDU 1102 Constructing Roads (Kruscal最小生成树)

   文章作者:ktyanny 文章来源:ktyanny 转载请注明,谢谢合作。 

 

   题目的大概意思是:给出n个村庄和这n个村庄两两之间的距离,同时,还告诉你那些村庄之间其实已经有路了。那么,现在要修路使得任意两个村庄可达,已经有路的不必修,那么聪明的你要编写一个程序计算最小的应该修的路的总距离ans。

  ktyanny大体思路: 明显是最小生成树问题,那么刚好昨天学习了Kruscal算法,派上用场了。用一个二维矩阵dis[][]保存输入数据,如果两个村庄之间已经有路了,那么就让这两个村庄相当于无限地接近,也就是把它们之间的距离处理为0;接下来就可以用经典的Kruscal算法来解决这个问题了。不懂Kruscal算法的同学可以点击最小生成树 Kruscal经典算法进行学习。

  46MS C++

/*
by ktyanny 2009.12.11
46MS 
*/
#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< string .h >

const   int  MAX  =   105 ;

typedef 
struct
{
    
int  x, y;
    
int  w;
}edge;
const   int  MAXN  =   50005 ;
edge e[MAXN];
int  ans;

int  rank[MAXN];
int  pa[MAXN];

void  make_set( int  x)
{
    pa[x] 
=  x;
    rank[x] 
=   0 ;
}

int  find_set( int  x)
{
    
if (x  !=  pa[x])
        pa[x] 
=  find_set(pa[x]);
    
return  pa[x];
}

/* 按秩合并x,y所在的集合 */
void  union_set( int  x,  int  y,  int  w)
{
    x 
=  find_set(x);
    y 
=  find_set(y);
    
if (x  ==  y) return  ;
    ans 
+=  w;
    
if (rank[x]  >  rank[y]) /* 让rank比较高的作为父结点 */
    {
        pa[y] 
=  x;
    }
    
else  
    {
        pa[x] 
=  y;
        
if (rank[x]  ==  rank[y])
            rank[y]
++ ;
    }
}

int cmp(const void *a, const void *b)
{
    
return ( (*(edge *)a).w > (*(edge *)b).w ) ? 1 : -1;
}


int  main()
{
    
int  n, t, i, j, k, x, y;
    
int  dis[MAX][MAX];
    
while (scanf( " %d " & n)  ==   1 )
    {
        
for (i  =   1 ; i  <=  n; i ++ )
            
for (j  =   1 ; j  <=  n; j ++ )
                scanf(
" %d " & dis[i][j]);
        scanf(
" %d " & t);
        
for (i  =   0 ; i  <  t; i ++ )
        {
            scanf(
" %d%d " & x,  & y);
            dis[x][y] 
=   0 ;
        }
        
/* 处理边集 */
        k 
=   0 ;
        ans 
=   0 ;
        
for (i  =   1 ; i  <=  n; i ++ )
        {
            
for (j  =   1 ; j  <=  n; j ++ )
            {
                e[k].w 
=  dis[i][j];
                e[k].x 
=  i;
                e[k].y 
=  j;
                k
++ ;
            }
        }

        qsort(e, k, 
sizeof (e[ 0 ]), cmp);

        
for (i  =   1 ; i  <=  n; i ++ )
            make_set(i);
        
        
for (i  =   0 ; i  <  k; i ++ )
        {
            x 
=  find_set(e[i].x);
            y 
=  find_set(e[i].y);
            
if (x  !=  y)
                union_set(x, y, e[i].w);
        }
        printf(
" %d\n " , ans);
    }
    
return   0 ;
}

 

   好吧,15:27了,是时候跑去上剩下的课了

 

你可能感兴趣的:(struct)