其他分享
首页 > 其他分享> > HDU 1102 Constructing Roads (Kruscal最小生成树)

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

 

转载于:https://www.cnblogs.com/ktyanny/archive/2009/12/11/1621969.html

标签:HDU,set,Constructing,int,rank,Kruscal,pa,find
来源: https://blog.csdn.net/weixin_34306676/article/details/93965880