【lightoj】1263 - Equalizing Money

1263 - Equalizing Money
Time Limit: 2 second(s)Memory Limit: 32 MB

There are n people in a certain village. Each of them contains some amount of money. One day a wise person told them to distribute the money such that everyone has equal amount of money. If they can do so, they will be favored by their fortunes.

You are given the information about the money of each person and some relations. Each relation is of the formu v. That means person u and v are capable of making money transactions. They are allowed to use transactions any number of times but they have to do integer transactions only.

Now your task is to answer whether they can redistribute the money such that each of them contains exactly same of money.

Input

Input starts with an integer T (≤ 100), denoting the number of test cases.

Each case starts with a line containing an integer n (2 ≤ n ≤ 1000) and m (0 ≤ m ≤ 10000) wherem denotes the number of relations. The next line contains n space separated integers ranging from 0 to 1000. Theith integer of this line denotes the money for the ith person. Each of the next m lines contains two integersu v (1 ≤ u, v ≤ n, u ≠ v) meaning that person u andv can make transactions. No relation is reported more than once.

Output

For each case, print the case number and 'Yes' if they can equalize their money or'No' otherwise.

Sample Input

Output for Sample Input

3

5 4

1 0 1 1 2

1 2

2 3

3 4

4 5

2 1

5 10

1 2

4 2

1 1 0 2

1 2

2 3

Case 1: Yes

Case 2: No

Case 3: No

Note

Dataset is huge, use faster I/O methods.

不知道哪里出错了。。有时间再看一遍。唉~~

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int f[1010],a[1010];
int find(int x)
{
	if(x!=f[x])
	f[x]=find(f[x]);
	return f[x];
}
void unio(int x,int y)
{
	int xx=find(x);
	int yy=find(y);
	if(xx!=yy)
	f[yy]=xx;
 } 
 struct Node
 {
 	int x;int y;
 }s[1010];
int main()
{
	int t;
	scanf("%d",&t);
	int k=1;
	while(t--){
		int n,m,c,d;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++) f[i]=i;//初始化 
		int sum=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			sum+=a[i];
		}
		for(int i=1;i<=m;i++){
			scanf("%d%d",&c,&d);
			unio(c,d);
		} 
		int faut=1;
		for(int i=1;i<=n;i++){
			s[i].x=0;s[i].y=0;
		}
		for(int i=1;i<=n;i++){
				s[f[i]].x+=a[i];s[f[i]].y+=1;
		}
			for(int i=1;i<=n;i++){
			//	printf("%d %d\n",s[f[i]].x,s[f[i]].y);
					if((s[f[i]].x%s[f[i]].y!=0)||(s[f[i]].x/s[f[i]].y!=sum/n)){
						faut=0;break;
					}
			}
			if(sum%n!=0) faut=0;
		if(faut) printf("Case %d: Yes\n",k++);
		else printf("Case %d: No\n",k++);	
	}
	return 0;
 } 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值