HDOJ 1233 还是畅通工程

题目传送:HDOJ 1233

解题思路:Kruskal算法,利用Kruskal算法获得最小生成树,即可求得答案。

数据结构:记录下起始坐标,结束坐标,两点距离和该路是否被选中这四个信息。

View Code
struct EDGE{
    int x;//起始坐标
    int y;//结束坐标
    int len;//距离
    int fg;//标记是否被选中
}

过程:

      1、读取所有路径信息,保存在上述数据结构的数组中;

      2、快速排序,使得数组中的数据结构按路径长度从小到大排列;

      3、优先选择路径较短的建树,此处为for循环;

      4、建树过程中,利用并查集判断该路是否会产生回路,如果回路则抛弃;

      5、直到生成一棵树覆盖所有坐标(城市)为止。

 题目代码:

#include <stdio.h>
#include <stdlib.h>

struct EDGE{
    int x,y,len,fg;
}edge[5000];

int father[110];

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

int find(int a)
{
    while(father[a]!=a)
        a=father[a];

    return a;
}

int merge(int x,int y)
{
    int fx,fy;

    fx=find(x);
    fy=find(y);
    if(fx==fy)
        return 0;
    else
    {
        father[fy]=fx;
        return 1;
    }
}

int main()
{
    int n,num,sum,i,p;
    
    while(scanf("%d", &n) && n)
    {
        num=n*(n-1)/2;//边数

        //初始化father[]
        for(i=1;i<=n;i++)
            father[i]=i;

        for(i=0;i<num;i++)
        {
            scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].len);
            edge[i].fg=0;
        }
        qsort(edge,num,sizeof(edge[0]),cmp);

        p=1;//初始化判断位p,1为选择,0为抛弃
        sum=0;//初始化sum,记录最短路径长度
        for(i=0;i<num;i++)
        {
            //利用并查集判断边的两点是否在同一集合内,不在就选择该边,否则抛弃
            p=merge(edge[i].x, edge[i].y);
            if(!p)
                continue;
            else
            {
                edge[i].fg=1;
                sum+=edge[i].len;
            }
        }

        printf("%d\n", sum);
    }

    return 0;
}

 

posted @ 2012-12-22 20:43  任琦磊  阅读(268)  评论(0编辑  收藏  举报