描述
刁姹(cha)接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的。账本上记录了 n 个月以来的收入情况,其中第 i 个月的收入额为Ai(i=1,2,3…n−1,n), 。当 Ai 大于 0 时表示这个月盈利 Ai 元,当 Ai 小于0时表示这个月亏损 Ai 元。所谓一段时间内的总收入,就是这段时间内每个月的收入额的总和。 刁姹的任务是秘密进行的,为了调查商人的账本,她只好跑到商人那里打工。她趁商人不在时去偷看账本,可是她无法将账本偷出来,每次偷看账本时她都只能看某段时间内账本上记录的收入情况,并且她只能记住这段时间内的总收入。
现在,刁姹总共偷看了 m 次账本,当然也就记住了 m 段时间内的总收入,你的任务是根据记住的这些信息来判断账本是不是假的。
输入描述
第一行为一个正整数 w,其中 w<100,表示有 w 组数据,即 w 个账本,需要你判断。每组数据的第一行为两个正整数 n 和 m,其中 n<100,m<1000,分别表示对应的账本记录了多少个月的收入情况以及偷看了多少次账本。接下来的 m 行表示刁姹偷看 m 次账本后记住的 m 条信息,每条信息占一行,有三个整数 s,t 和 v ,表示从第 s 个月到第 t 个月(包含第 t 个月)的总收入为 v,这里假设s总是小于等于 t。
输出描述
包含 w 行,每行是 true 或 false,其中第 i 行为 true 当且仅当第 i 组数据,即第 i 个账本不是假的;第 i 行为 false 当且仅当第 i 组数据,即第 i 个账本是假的。
样例输入 1
2 3 3 1 2 10 1 3 -5 3 3 -15 5 3 1 5 100 3 5 50 1 2 51
样例输出 1
true false
#include<bits/stdc++.h>
using namespace std;
int n,m,w;
int fa[100010],d[100010];
int find(int x){
if(fa[x]==x) return x;
int temp=find(fa[x]);
d[x]+=d[fa[x]];
return fa[x]=temp;
}
int merge(int x,int y,int v){
int fx=find(x);
int fy=find(y);
if(fx==fy){
return d[x]-d[y]==v;
}
if(fx<fy){
fa[fx]=fy;
d[fx]=v+d[y]-d[x];
return 1;
}else{
fa[fy]=fx;
d[fy]=d[x]-d[y]-v;
return 1;
}
}
int main(){
cin>>w;
while(w--){
cin>>n>>m;
memset(d,0,sizeof(d));
for(int i=0;i<=n;i++){
fa[i]=i;
}
int s,t,v;
int flag=1;
for(int i=1;i<=m;i++){
cin>>s>>t>>v;
if(flag==0) continue;
if(merge(s-1,t,v)==0){
flag=0;
}
}
if(flag) cout<<"true"<<endl;
else cout<<"false"<<endl;
}
return 0;
}
863

被折叠的 条评论
为什么被折叠?



