• 并查集的应用


    时间复杂度为O(m log n)

    若m远大于n可以视为O(m)

    一般为路径压缩

    关系类并查集,以食物链为代表

    个人感觉还是蛮重要的,主要是一个偏移量的关系

    代码如下

    #include<cstdio>
        int a[150001];
        int n,k,d,x,y,ans=0;
    int find(int x)
    {
        if(x!=a[x]) a[x]=find(a[x]);
        return a[x];
    }
    void go(int x,int y)
    {
        x=find(x);
        y=find(y);
        a[x]=y;
    }
    int main()
    {
        scanf("%d %d",&n,&k);
        for(int i=1;i<=3*n;i++)
            a[i]=i;
        for(int i=1;i<=k;i++)
        {
            scanf("%d %d %d",&d,&x,&y);
            if(x>n||y>n)
            {
                ans++;
                continue;
            }
            if(d==1)
            {
                if(find(x+n)==find(y)||find(x+n*2)==find(y))
                {
                    ans++;
                    continue;
                }
                go(x,y);
                go(x+n,y+n);
                go(x+2*n,y+2*n);
            }
            else
            {
                if(find(x)==find(y)||find(x+2*n)==find(y))
                {
                    ans++;
                    continue;
                }
                go(x+n,y);
                go(y+2*n,x);
                go(y+n,x+2*n); 
            }
        }
        printf("%d",ans);
    }

    还有一类题目是带权并查集,tg这个范围应该差不多了

    并查集 专题 - Virtual Judge.html

    https://vjudge.net/contest/155624#problem/D

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int MAXN=200010;
    int fa[MAXN];
    int val[MAXN];
    int n,m;
    
    int findfa(int x)
    {
        if(fa[x]==-1) return x;
    
        int tmp=findfa(fa[x]);
        val[x]+=val[fa[x]];
    
        return fa[x]=tmp;
    }
    
    int main()
    {
        int u,v,w;
    
        while(~scanf("%d %d",&n,&m))
        {
            memset(fa,-1,sizeof fa);
            memset(val,0,sizeof val);
    
            int ans=0;
    
            while(m--)
            {
                scanf("%d %d %d",&u,&v,&w);
                u--;
    
                int xx=findfa(u);
                int yy=findfa(v);
    
                if(xx==yy)
                {
                    if( (val[v]-val[u])!=w)
                    ans++;
                }
                else
                {
                    fa[yy]=xx;
                    val[yy]=val[u]-val[v]+w;
                }
            }
    
            printf("%d
    ",ans);
    
        }
    }
  • 相关阅读:
    关于带权并查集
    Connections in Galaxy War ZOJ
    Supermarket POJ
    并查集判树 poj 1308
    最长异或值路径【字典树应用】
    最大异或对
    trie字典树【模板题】
    UVA536 二叉树重建 Tree Recovery
    UVA1584环状序列 Circular Sequence
    【CodeForces 622F】The Sum of the k-th Powers
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/6738515.html
Copyright © 2020-2023  润新知