UVA11690 HDU3140 Money Matters【并查集】

708 篇文章 18 订阅
48 篇文章 1 订阅

Our sad tale begins with a tight clique of friends. Together they went on a trip to the picturesque country of Molvania. During their stay, various events which are too horrible to mention occurred. The net result was that the last evening of the trip ended with a momentous exchange of “I never want to see you again!”s. A quick calculation tells you it may have been said almost 50 million times!
    Back home in Scandinavia, our group of ex-friends realize that they haven’t split the costs incurred during the trip evenly. Some people may be out several thousand crowns. Settling the debts turns out to be a bit more problematic than it ought to be, as many in the group no longer wish to speak to 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 much money she owes or is owed, and whom she is still friends with. Given this information, you’re sure you can figure out if it’s possible for everyone to get even, and with money only being given between persons who are still friends.
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). The sum of these values is zero. After this comes m lines giving the remaining friendships, 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’ or ‘IMPOSSIBLE’.
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

问题链接UVA11690 HDU3140 Money Matters
问题简述:(略)
问题分析
    简单的并查集问题,看代码不解释。
    HDU与UVA的输入数据格式不同。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序(UVA)如下:

/* UVA11690 Money Matters */

#include <bits/stdc++.h>

using namespace std;

const int N = 10000;
int f[N], w[N];

void UFInit(int n)
{
    for(int i = 0; i < n; i++)
        f[i] = i;
}

int Find(int a) {
    return a == f[a] ? a : f[a] = Find(f[a]);
}

void Union(int a, int b)
{
    a = Find(a);
    b = Find(b);
    if (a != b) {
        f[a] = b;
        w[b] += w[a];
    }
}

int main()
{
    int t, n, m;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &m);

        UFInit(n);

        for(int i = 0; i < n; i++)
            scanf("%d", &w[i]);

        for(int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            Union(u, v);
        }

        int i;
        for(i = 0; i < n; i++)
            if(w[Find(i)] != 0)
                break;

        puts(i == n ? "POSSIBLE" : "IMPOSSIBLE");
    }

    return 0;
}

AC的C++语言程序(HDU)如下:

/* HDU3140 Money Matters */

#include <bits/stdc++.h>

using namespace std;

const int N = 10000;
int f[N], w[N];

void UFInit(int n)
{
    for(int i = 0; i < n; i++)
        f[i] = i;
}

int Find(int a) {
    return a == f[a] ? a : f[a] = Find(f[a]);
}

void Union(int a, int b)
{
    a = Find(a);
    b = Find(b);
    if (a != b) {
        f[a] = b;
        w[b] += w[a];
    }
}

int main()
{
    int n, m;
    while(~scanf("%d%d", &n, &m)) {
        UFInit(n);

        for(int i = 0; i < n; i++)
            scanf("%d", &w[i]);

        for(int i = 0; i < m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            Union(u, v);
        }

        int i;
        for(i = 0; i < n; i++)
            if(w[Find(i)] != 0)
                break;

        puts(i == n ? "POSSIBLE" : "IMPOSSIBLE");
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值