HDU 1863 畅通工程 解题报告 (Kruskal)

看题传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1863

 

这题是最小生成树的裸题,具体的算法内容挺简单的,记录一下实现过程中踩的坑……

首先这题用优先队列应该是最简单的,直接在结构体里重载运算符,我tm只记得用队列方便,却忘了优先队列更方便……像这种判断连通分量的,循环看看谁的父亲是自己就行了。

再一个就是kruskal算法里merge函数最后要有返回值以判断连接是否成功。

自己实现的时候千难万难,回过头来再看又觉得没什么。

上一波实现吧

#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;
const int MAXN = 11000;
int fa[MAXN];
struct Edge{
    int u, v;
    int w;
}Graph[MAXN];

int getFa(int a){
    return fa[a] == a? a : fa[a] = getFa(fa[a]);
}
int Merge(int a, int b){
    int faA = getFa(a), faB = getFa(b);
    if(faA != faB){
        fa[faA] = faB;
        return 1;
    }
    else
        return 0;
}
bool cmp(Edge a, Edge b){
    if(a.w != b.w)
        return (a.w < b.w);
}

int main()
{
    //freopen("input.txt", "r", stdin);
    int n, m;
    while(~scanf("%d %d", &n, &m) && n){
        for(int i = 0;i < n;++i){
            scanf("%d %d %d", &Graph[i].u, &Graph[i].v, &Graph[i].w);
        }
        if(n < m-1){
            printf("?\n");
            continue;
        }
        for(int i = 1;i <= m;++i)
            fa[i] = i;

        sort(Graph, Graph + n, cmp);
        queue<Edge> qu;
        for(int i = 0;i < n;++i){
            qu.push(Graph[i]);
        }

        int ans = 0;
        bool flag = true;
        for(int i = 0;i < n;i++){
            if(Merge(qu.front().u, qu.front().v) ){
               ans += qu.front().w;
            }
            qu.pop();
        }

        int cnt = 0;
        for(int i = 1;i <= m;++i){
            if(fa[i] == i){
                cnt++;
            }
        }

        if(cnt == 1)
            printf("%d\n",ans);
        else
            printf("?\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/aldo101/article/details/81087457