还是畅通工程

还是畅通工程

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;
}
全部评论

相关推荐

看到这个内容真是闹麻了。。。。。。现在有了AI以后很多人面试都会作弊吗?&nbsp;那对老老实实面试的人岂不是不公平....
程序员牛肉:公平那是对小孩子讲的童话故事,成年人的世界只有能不能接受失败的后果。 你要是能接受面试作弊被发现之后多家公司联合永久拉黑的后果,你就搞。
点赞 评论 收藏
分享
06-02 15:53
阳光学院 Java
点赞 评论 收藏
分享
05-13 02:01
已编辑
惠州学院 前端工程师
安静的少年在求佛:建议把公司名字写到标题。以后有人想搜就能直接搜到
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务