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

来源:互联网 发布:女明星 瘦 知乎 编辑:程序博客网 时间:2024/05/17 01:25

题目概述

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

解题报告

带权并查集套路题,每次多出来一条信息 (x,y,z) 可以看做是 x1y 连边,且 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.
原创粉丝点击