UVa11690 - Money Matters(并查集)

Problem B - Money Matters


Time limit: X seconds


Our sad tale begins with a tight clique of friends. Together they went on atrip to the picturesque country of Molvania. During their stay, various eventswhich are too horrible to mention occurred. The net result was that the lastevening of the trip ended with a momentous exchange of ``I never want to seeyou again!''s. A quick calculation tells you it may have been said almost 50million times!

Back home in Scandinavia, our group of ex-friends realize that they haven'tsplit the costs incurred during the trip evenly. Some people may be outseveral thousand crowns. Settling the debts turns out to be a bit moreproblematic than it ought to be, as many in the group no longer wish to speakto one another, and even less to give each other money.

Naturally, you want to help out, so you ask each person to tell you how muchmoney she owes or is owed, and whom she is still friends with. Given thisinformation, you're sure you can figure out if it's possible for everyone toget even, and with money only being given between persons who are stillfriends.

Input


The first line of the input file contains an integer N (N<=20) which denotes the total number of test cases.The description of each test case is given below:

The first line contains two integers, n (2 ≤ n ≤ 10000), and m (0 ≤ m≤ 50000), the number of friends and the number of remaining friendships.Then n lines follow, each containing an integer o (-10000 ≤ o≤ 10000) indicating how much each person owes (or is owed if o < 0). Thesum of these values is zero. After this comes m lines giving the remainingfriendships, each line containing two integers x, y (0 ≤ x < y ≤n-1) indicating that persons x and y are still friends.

Output


For each test case your output should consist of a single line saying POSSIBLE orIMPOSSIBLE.

Sample Input

2
5 3
100
-75
-25
-42
42
0 1
1 2
3 4
4 2
15
20
-10
-25
0 2
1 3


Sample Output

POSSIBLE
IMPOSSIBLE


import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main 
{
	private static final boolean DEBUG = false;
	private BufferedReader cin;
	private PrintWriter cout;
	private StreamTokenizer tokenizer;
	private int n, m;
	private int[] money, p;
	
	public void init() 
	{
		try {
			if (DEBUG) {
				cin = new BufferedReader(new InputStreamReader(
						new FileInputStream("d:\\OJ\\uva_in.txt")));
			} else {
				cin = new BufferedReader(new InputStreamReader(System.in));
			}
			cout = new PrintWriter(new OutputStreamWriter(System.out));
			tokenizer = new StreamTokenizer(cin);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String next()
	{ 
		try {
			tokenizer.nextToken();
			if (tokenizer.ttype == StreamTokenizer.TT_EOF) return null;
			else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) 
				return String.valueOf((int)tokenizer.nval);
			else return tokenizer.sval;
			
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}	
	}
	
	public boolean input() 
	{	
		n = Integer.parseInt(next());
		m = Integer.parseInt(next());
		
		p = new int[n];
		money = new int[n];
		for (int i = 0; i < n; i++) {
			p[i] = i;
		}
		
		for (int i = 0; i < n; i++) {
			money[i] = Integer.parseInt(next());
		}
		return true;
	}
	
	private int find(int x)
	{
		int root = x;
		
		while (p[root] != root) {
			root = p[root];
		}
		
		while (p[x] != root) {
			int tmp = x;
			x = p[x];
			p[tmp] = root;
		}
		return root;
	}
	
	private void Union(int a, int b)
	{
		int pa = find(a);
		int pb = find(b);
		
		if (pa == pb) return;
		
		p[pb] = pa;
		money[pa] += money[pb];
	}
	
	public void solve() 
	{
		for (int i = 0; i < m; i++) {
			int a = Integer.parseInt(next());
			int b = Integer.parseInt(next());
		
			Union(a, b);
		}
		
		boolean ok = true;
		for (int i = 0; i < n; i++) {
			if (money[find(i)] != 0) {
				ok = false;
				break;
			}
		}
		
		if (ok) cout.println("POSSIBLE");
		else cout.println("IMPOSSIBLE");
		cout.flush();
	}

	public static void main(String[] args) 
	{
		Main solver = new Main();
		solver.init();
		
		int t = Integer.parseInt(solver.next());
		while (t-- > 0) {
			solver.input();
			solver.solve();
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值