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了,是时候跑去上剩下的课了

 

posted on 2009-12-11 15:28  Ktyanny Home  阅读(1011)  评论(0编辑  收藏  举报

导航