CSP-S 例题9-1 狡猾的商人(HNOI2005)

描述

刁姹(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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值