还是畅通工程

还是畅通工程

http://www.nowcoder.com/questionTerminal/d6bd75dbb36e410995f8673a6a2e2229

典型的最小生成树问题
如何生成最小生成树 --> prim、Kruskal算法
选用Kruskal算法,如何判断两个顶点已经在同一集合? --> 并查集
注意qsort对指针数组的应用

#include<stdio.h>
#include<stdlib.h>
typedef struct{
    int cost;
    int x;
    int y;
}Edge; // 边结构体
Edge *E[5100];
int father[101];
int cmp(const void *a,const void *b)
{
    Edge * x = *(Edge **)a;
    Edge * y = *(Edge **)b;
    return x->cost - y->cost;
}
void init()
{
    for(int i = 0;i<101;i++)
        father[i] = i;
    return;
}
int findfather(int i)
{
    if(father[i] == i)
        return i;
    else
        return findfather(father[i]);
}
int main()
{
    int N;
    while(scanf("%d",&N) != EOF && N)
    {
        int ans = 0;
        init(); // 初始化father数组
        for(int i = 0;i<N*(N-1) / 2; i++) // 读取边的信息
        {
            E[i] = (Edge *)malloc(sizeof(Edge));
            scanf("%d %d %d",&E[i]->x,&E[i]->y,&E[i]->cost);
        }
        qsort(E,N*(N-1) / 2,sizeof(Edge*),cmp); // 按边的权值升序排列
        int cnt = 0; // 计数目前最小生成树的边
        for(int i = 0;i<N*(N-1)/2;i++) // 利用Kruskal算法构造最小生成树
        {
            if(cnt == N-1) // 最小生成树已经构造好
                break;
            int fx = findfather(E[i]->x);
            int fy = findfather(E[i]->y);
            if(fx != fy) // 边的两端点不在同一集合中则合并
            {
                father[fx] = fy;
                ans += E[i]->cost;
                cnt++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
全部评论

相关推荐

小谷围鸡肉卷阿姨:+1,腾子投完一动不动
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务