码迷,mamicode.com
首页 > 其他好文 > 详细

带权值的并查集

时间:2019-09-28 14:43:47      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:space   details   例题   int   color   end   ref   lse   hdu   

博文: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;
    }
}

 hihoCoder 1515

//带权并查集
#include<iostream>
#include<cstdio>//不是同一集合,合并,否则不做操作
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5 + 15;
int dis[maxn],p[maxn];//当前node到root的距离
int find(int u)
{
    if(u!=p[u])
    {
        int tmp = p[u];
        p[u] = find(p[u]);
        dis[u] += dis[tmp];
    }
    return p[u];
}
int main()
{
    int n,m,q;//n个节点,m条边,q个查询
    while(cin>>n>>m>>q)
    {
        for(int v=1;v<=n;++v)
        {
            dis[v] = 0;
            p[v] = v;
        }
        int u,v,value;
        while(m--)
        {
            cin>>u>>v>>value;
            int f1 = find(u);
            int f2 = find(v);
            if(f1!=f2)
            {
                p[f1] = f2;
                dis[f1] = value + dis[v] - dis[u];
            }
        }
        while(q--)
        {
            cin>>u>>v;
            if(find(u)!=find(v))
                cout<<-1<<endl;
            else
                cout<<dis[u] - dis[v]<<endl;
        }
    }
}  

  

带权值的并查集

标签:space   details   例题   int   color   end   ref   lse   hdu   

原文地址:https://www.cnblogs.com/newstartCY/p/11601164.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!