【带权并查集】BZOJ1202(HNOI2005)[狡猾的商人]题解

题目概述

调查一位商人的账本,账本上记录了 n 个月以来的收入情况。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。共看了 m 次账本,只能看某段时间内账本上记录的收入情况,并且只能记住这段时间内的总收入。根据记住的这些信息来判断账本是不是假的。

解题报告

带权并查集套路题,每次多出来一条信息 (x,y,z) 可以看做是 x1 y 连边,且 SySx1=z ,那么这样就可以判断 [L,R] 的区间和是否已知,所以和题目里给的信息核对一下就行了。

示例程序

QAQ果断偷懒,这是以前写的pascal代码。

var t,n,m,i:longint;
    father,sum:array[0..105] of longint;
    can:boolean;
 procedure init;
  var i:longint;
   begin
     readln(n,m);
   end;
 function get(x:longint):longint;
  var fa:longint;
   begin
     if father[x]=x then exit(x);
     fa:=father[x];
     father[x]:=get(father[x]);
     inc(sum[x],sum[fa]);
     exit(father[x]);
   end;
 procedure main;
  var i,x,y,fx,fy,tot:longint;
   begin
     can:=true;
     for i:=0 to n do begin father[i]:=i;sum[i]:=0; end;
     for i:=1 to m do
       begin
         readln(x,y,tot);
         if not can then continue;
         fx:=get(x-1);
         fy:=get(y);
         if fx<>fy then
           begin
             father[fx]:=fy;
             sum[fx]:=sum[y]-sum[x-1]-tot;
           end else if sum[y]-sum[x-1]<>tot then can:=false;
       end;
   end;
 procedure print;
  begin
    if can then writeln('true')
           else writeln('false');
  end;
begin
  assign(input,'program.in');reset(input);
  assign(output,'program.out');rewrite(output);
  readln(t);
  for i:=1 to t do
    begin
      init;
      main;
      print;
    end;
  close(input);close(output);
end.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值