Problem - 376B - Codeforces

点击打开链接

                                                                                                                 B. I.O.U.


Imagine that there is a group of three friends: A, B and С. A owes B 20 rubles and B owes C 20 rubles. The total sum of the debts is 40 rubles. You can see that the debts are not organized in a very optimal manner. Let's rearrange them like that: assume that A owes C 20 rubles and B doesn't owe anything to anybody. The debts still mean the same but the total sum of the debts now equals 20 rubles.

This task is a generalisation of a described example. Imagine that your group of friends hasn people and you know the debts between the people. Optimize the given debts without changing their meaning. In other words, finally for each friend the difference between the total money he should give and the total money he should take must be the same. Print the minimum sum of all debts in the optimal rearrangement of the debts. See the notes to the test samples to better understand the problem.

Input

The first line contains two integers n andm (1 ≤ n ≤ 100; 0 ≤ m ≤ 104). The nextm lines contain the debts. The i-th line contains three integers ai, bi, ci(1 ≤ ai, bi ≤ nai ≠ bi; 1 ≤ ci ≤ 100), which mean that person ai owes personbici rubles.

Assume that the people are numbered by integers from 1 to n.

It is guaranteed that the same pair of people occurs at most once in the input. The input doesn't simultaneously contain pair of people(x, y) and pair of people (y, x).

Output

Print a single integer — the minimum sum of debts in the optimal rearrangement.

Sample test(s)
Input
5 3
1 2 10
2 3 1
2 4 1
Output
10
Input
3 0
Output
0
Input
4 3
1 2 1
2 3 1
3 1 1
Output
0

该题的意思就是求一共欠多少债务,此题难点在于一个人不止欠别人欠,还可能别人欠他的钱。

我开始时想成啦求最大的欠债量,前三个样列也对,但是错在啦第四个样列,后来仔细想拉想,应该是所有人欠债的总和

我想到的是开两个数组,a[i]表示第i 个人所欠的钱,b[i]表示的是第i个人获得的钱。一个人所欠的钱减去获得的钱就是他的

债务啦!

#include<iostream>
#include<cstdio>

int main()
{
    int  n,m;
    while(scanf("%d %d",&n,&m) != EOF)
    {
       int a[105] = {0},b[105] = {0};
        int i,j,maxn = 0;
        int k,p,q;
        if(m == 0)
            printf("%d\n",maxn);
        else
        {
            for(i = 1;i <= m;i++)
            {
                scanf("%d%d%d",&k,&p,&q);
                a[k] += q;
                b[p] += q;
            }
        for(i = 1;i <= n;i++)
        {
            if(b[i] >= a[i])          //如果他所获得的钱大于欠的钱,则他的债务a[i]为0;
            {
                b[i] = b[i] - a[i];
                a[i] = 0;
            }
            else
                a[i] = a[i] - b[i];
        }
        for(i = 1;i <= n;i++)
        {
            maxn += a[i];
        }
        printf("%d\n",maxn);
        }
    }
    return 0;
}

下面附上大神的代码:

我看见他的代码有点惊讶,大神的思维就是好,这样的办法都想的出来。一个人所欠的所有债务减去他所获得的钱就是他最终所欠的债

#include<iostream>
using namespace std;
int a[101],n,m,x,y,j,sum;
int main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y>>j;
		a[x]-=j;
		a[y]+=j;
	}
	for(int i=1;i<=n;i++)if(a[i]>0)sum+=a[i];
	cout<<sum;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值