带权值的并查集

博文:https://blog.csdn.net/yjr3426619/article/details/82315133

带全并查集

路径压缩,表达每个当前node与 当前node所在的并查集的root 之间的关系

并查集一定是单向连通的,所以一些node处理时 【node1,node2】 weight 可能需要把 一端的闭区间变为开区间

俩个相对信息求出绝对信息   --水题

例题 : HDU 3038 

//带权值并查集
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e5 + 25;
int dis[maxn];
int p[maxn];
int find(int u)//寻根
{
    if(u!=p[u])
    {
        int tmp = p[u];//保存原来的根节点
        p[u] = find(p[u]);//路径压缩
        dis[u] += dis[tmp];//dis[tmp] 已经为tmp(即原来父节点)到根节点的距离所以加上本身自身到tmp的dis则为u到root的dis  
    }
    return p[u];
}
void merge(int u,int v,int value)
{
    int f1 = find(u);
    int f2 = find(v);
    p[f1] = f2;
    dis[f1] = value + dis[v] - dis[u];
}//带权并查集合并
int main()
{
    int n,m;//n节点,m条边
    while(cin>>n>>m)
    {
        int ans = 0,u,v,value;
        for(int i=0;i<=n;++i)
        {
            dis[i] = 0;
            p[i] = i;
        }
        while(m--)
        {//图改成了从0开始(important)
            cin>>u>>v>>value;
            --u;
            if(find(u)==find(v))
            {
                if((dis[u]-dis[v])!=value)
                    ++ans;
            }else{
                merge(u,v,value);//否则合并
            }
        }
        cout<<ans<<endl;
    }
}

猜你喜欢

转载自www.cnblogs.com/newstartCY/p/11601164.html
今日推荐