zoukankan      html  css  js  c++  java
  • 并查集(带路径压缩)

    并查集

    用于快速查找集合中元素是否存在关系的数据结构,主要操作为:查询合并
    并查集简述

    常用的带有路径压缩版本的并查集模板:

    带路径压缩的并查集在一般情况下的查询或者合并操作,其时间复杂度近似于O(1)

    #define MAXN 5000
    int fa[MAXN+1];
    void init(int n)
    {
        for(int i = 1; i <= n; i++)
        {
            fa[i] = i; //初始化
        }
    }
    
    int find(int x)
    {
        if(fa[x]==x)
            return x;
        return fa[x] = find(fa[x]); //查询时进行路径压缩
    }
    
    void merge(int x, int y)
    {
        fa[find(x)] = find(y); //合并
    }
    

    实战1:P1111修复公路



    思路:这题本质要求我们权为时间t的图的最小生成树,具体做法为:先将边按时间从小到大排序,然后依次判断取边,当构成生成树(下为ans==n-1)时即输出答案即可

    赋AC代码:

    #include <stdio.h>
    #include <stdlib.h>
    #define MAXN 1000
    int fa[MAXN+1];
    typedef struct maye
    {
        int u, v, t;
    }ccc;
    void init(int n)
    {
        for(int i = 1; i <= n; i++)
        {
            fa[i] = i; //初始化
        }
    }
    
    int find(int x)
    {
        if(fa[x]==x)
            return x;
        return fa[x] = find(fa[x]); //查询时进行路径压缩
    }
    
    void merge(int x, int y)
    {
        fa[find(x)] = find(y); //合并
    }
    
    int com(const void *a, const void *b)
    {
        return (*(ccc *)a).t - (*(ccc *)b).t;
    }
    int main(void)
    {
        int n, m, ans = 0;
        scanf("%d %d",&n,&m);
        init(n);
        ccc path[m+1];
        for(int i = 1; i <= m; i++)
        {
            scanf("%d %d %d",&path[i].u,&path[i].v,&path[i].t);
        }
        qsort(path+1, m, sizeof(ccc), com);
        for(int i = 1; i <= m; i++)
        {
            if(find(path[i].u)!=find(path[i].v))
                ans++;
            merge(path[i].u, path[i].v);
            if(ans==n-1)
            {
                printf("%d
    ",path[i].t);
                return 0;
            }
        }
        printf("-1
    ");
        return 0;
    }
    
    

    实战2:P1195口袋的天空


    思路:与上一题类似,同样将边按权从小到大排序,初始集合总数为n,然后对于每一条边,如果不连通,就选上并更新连通性(如果不用选就直接跳过),这样集合总数会-1,直到集合数为k时得到答案

    赋AC代码:

    #include <stdio.h>
    #include <stdlib.h>
    #define MAXN 1000
    int fa[MAXN+1];
    typedef struct maye
    {
        int u, v, l;
    }ccc;
    void init(int n)
    {
        for(int i = 1; i <= n; i++)
        {
            fa[i] = i; //初始化
        }
    }
    
    int find(int x)
    {
        if(fa[x]==x)
            return x;
        return fa[x] = find(fa[x]); //查询时进行路径压缩
    }
    
    void merge(int x, int y)
    {
        fa[find(x)] = find(y); //合并
    }
    
    int com(const void *a, const void *b)
    {
        return (*(ccc *)a).l - (*(ccc *)b).l;
    }
    int main(void)
    {
        int n, m, ans, k, answer = 0;
        scanf("%d %d %d",&n,&m,&k);
        ans = n;
        init(n);
        ccc path[m+1];
        for(int i = 1; i <= m; i++)
        {
            scanf("%d %d %d",&path[i].u,&path[i].v,&path[i].l);
        }
        qsort(path+1, m, sizeof(ccc), com);
        for(int i = 1; i <= m; i++)
        {
            if(find(path[i].u)==find(path[i].v))
                continue;
            merge(path[i].u, path[i].v);
            ans--;
            answer+=path[i].l;
            if(ans==k)
            {
                printf("%d
    ",answer);
                return 0;
            }
        }
        printf("No Answer
    ");
        return 0;
    }
    
    
  • 相关阅读:
    python全栈开发_day17_时间,系统模板和序列化
    python全栈开发_day15_函数回调和模块
    python全栈开发_day16_包
    pygame学习_part1_pygame写程序前的准备工作
    python全栈开发_day15_模块学习
    不确定性推理复习
    hibernate级联关系
    hibernate双向一对多关联关系
    实践:hibernate-one2many(单向)
    我的学习(修改完善)
  • 原文地址:https://www.cnblogs.com/SpicyArticle/p/12022514.html
Copyright © 2011-2022 走看看