带权并查集

题目链接:https://cn.vjudge.net/problem/HDU-3038

具体大意:给你多次询问,每一次输入三个值,前两个代表区间,最后一个代表这个区间的值。问你这多次询问中有几次时候矛盾的。

举个例题 

  1 2 3

1 2 4  ,这不就矛盾了,,,

具体思路:首先每一个点都是自己的区间,在每一次更新的过程中,这个点的父节点是当前点往前最多知道到哪个点的区间是清楚的。这样的话,每一次更新的时候,如果当前的区间已经知道了。比如说 3 4 5,那么就直接将1到4的距离减去1 2 的距离,得到的就是3 到5 的距离,然后再比较就可以了。

如果当前的区间不清楚,那么就需要更新,尽量往前更新。比如说 3 4 5,假设3的父亲节点1,  4的父亲节点是2

1 2 3 4

这样的话,就能够计算出1到2 的距离,也就是3的父亲节点和4的父亲节点的距离,然后再将4的父亲节点进行更新、

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 # define ll long long
 4 # define inf 0x3f3f3f3f
 5 const int maxn =2e5+100;
 6 int father[maxn];
 7 int sum[maxn];
 8 int Find(int t)
 9 {
10     if(t==father[t])
11         return t;
12     int tmp=father[t];
13         father[t]=Find(father[t]);
14         sum[t]+=sum[tmp];
15     return father[t];
16 }
17 int main()
18 {
19     int n,m;
20     while(~scanf("%d %d",&n,&m))
21     {
22         for(int i=0; i<=n; i++)
23         {
24             father[i]=i,sum[i]=0;
25         }
26         int ans=0;
27         int st,ed,val;
28         for(int i=1; i<=m; i++)
29         {
30             scanf("%d %d %d",&st,&ed,&val);
31             st--;
32             int t1=Find(st);
33             int t2=Find(ed);
34             if(t1==t2&&sum[ed]-sum[st]!=val)
35                 ans++;
36             else if(t1>t2)
37             {
38                 father[t1]=t2;
39                 sum[t1]=sum[ed]-sum[st]-val;
40             }
41             else if(t1<t2)
42             {
43                 father[t2]=t1;
44                 sum[t2]=sum[st]+val-sum[ed];
45             }
46         }
47         printf("%d\n",ans);
48     }
49     return 0;
50 }

 

转载于:https://www.cnblogs.com/letlifestop/p/10262891.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值