天天写算法之How Many Answers Are Wrong

本文介绍了一种使用并查集解决连通性问题的方法。通过具体实现细节,展示了如何利用并查集进行集合间的合并及查找操作,特别关注于如何定义和更新节点的val值,以确保正确处理数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目: 点击打开链接
这个题目和前面的几个题目很相似,都是通过left-1 与 right压栈,进行连通性比较,说明了一个问题,就是并查集可以用来处理这种集合求解,或者相似性去重的操作。这个个题的难点在于,如何规定val值,在注释中解释了。

代码
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#define repf(i,from ,to) for(int i =from;i<=to;i++)
#define MAX 200005
using namespace std;
int val[MAX],pre[MAX],ans;
void init(int n){
    repf(i,0,n)
    {
        pre[i]=i;
        val[i]=0;
    }
    ans=0;
}

int Find(int a)
{
    if(pre[a]!=a)
    {
        int temp = pre[a];
        pre[a]=Find(pre[a]);
        val[a]+=val[temp];
    }
    return pre[a];
}

void Merge(int a,int b,int si)
{
    int fa = Find(a);
    int fb = Find(b);
     //这个地方我们可以画几个图,主要是计算祖先的节点信息,原因是,计算完祖先的位置信息后,就可以通过Find进行更新。
     //比如 一条线是1    5   9 另一条线是2  4   8 
     //我们现在加进来了一个新的数据是5  8 ,那么怎么处理呢,我们需要让后面的数据的祖先变成前面的,为了统一。
     //另一个就是更新这个val值,更新谁的呢,当然是2的,然后再次Find的时候就会把后面的数据val值全部更新。
     if(fa>fb)
    {
        pre[fa]=fb;
        val[fa]=val[b]-val[a]-si ;
    }else if(fa<fb)
    {
        pre[fb] = fa;
        val[fb] = val[a]-val[b]+si;
    }
    else if(val[b]-val[a]!=si)
    {
        ans++;
    }

}
int n , m ;
int main(){
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        init(n);

        repf(i,1,m)
        {
            int ai,bi,si;
            scanf("%d%d%d",&ai,&bi,&si);
            ai--;

            Merge(ai,bi,si);
        }
        cout << ans <<endl;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值