hdu1863 畅通工程(kruscal && 并查集)

来源:互联网 发布:网络直播平台排行榜 编辑:程序博客网 时间:2024/06/16 09:10

kruskal里的判断是否有环相当于并查集判断有环,都是选出的两个点若有相同的根则有环,所以并查集的模板也可以用;

判断是否有最小生成树只需在遍历判断根节点相同时顺便统计其个数,最后判断是否相同即可;

和并查集联系起来,以后脑中就用一个模板就好了~

#include <stdio.h>#include <cstdio>#include <cstring>#include <algorithm>#include <string>using namespace std;const int N = 5005;int pre0[N];int n, sum, num;struct edges{    int pre;    int suc;    int wei;}edge[N];int cmp(edges x, edges y){    return (x.wei < y.wei) ? 1 : 0;}void init(int vs){    for(int i = 1; i <= vs; i ++)        pre0[i] = i;}int findd(int x){    int r = x;    while(r != pre0[r])        r = pre0[r];    pre0[x] = r;    int i = x, j;    if(i != r)    {        j = pre0[i];        pre0[i] = r;        i = j;    }    return r;}void Union(int x, int y, int z){    int f1, f2;    f1 = findd(x);    f2 = findd(y);    if(f1 != f2)    {        pre0[f2] = f1;        num ++;        sum += z;    }}int kruskal(int es, int vs){    num = 1;    sum = 0;    init(vs);    sort(edge, edge + es, cmp);    for(int i = 0; i < es; i ++)        Union(edge[i].pre, edge[i].suc, edge[i].wei);//    printf("%d %d %d\n", vs, num, sum);    if(num == vs) return sum;    else return -1;}int main(){  //  freopen("in.txt", "r", stdin);    int m, ans;    while(~scanf("%d%d", &n, &m) && n)    {        for(int i = 0; i < n; i ++)            scanf("%d%d%d", &edge[i].pre, &edge[i].suc, &edge[i].wei);        ans = kruskal(n, m);        if(ans == -1) printf("?\n");        else printf("%d\n", ans);    }    return 0;}


0 0