标签:int LL Debts CF num 简化 cnt2 cnt1 1266D
题目链接:
https://codeforces.com/problemset/problem/1266/D
题目大意:
有 \(n\) 个人,有 \(m\) 条债务关系,定义 \(d(a, b)\) 表示 \(a\) 欠 \(b\) 块钱,如果 \(c\) = 0,那么就相当于没有债务关系,现在想简化每个人之间的债务关系。
有以下两种简化方案,
1、当 d(a, b) > 0,d(c, d) > 0 且 a != c 或者 b != d 时,我们可以让 d(a, b),d(c, d) 都减去 z,d(c, b),d(a, d)都加上 z,0 < z <= min(d(a, b),d(c, d))。
2、当 d(a, a) > 0 时,我们可以设 d(a, a) = 0。
问最后能简化成什么怎样的关系,并将简化后的所有关系总数先输出,再依次输出每条关系。
思路:
在第一条简化方案中我们可以令 \(b = c\),那么我们可以分三种情况看。
当 d(a, b) > d(c, d) 时,d(a, b),d(c, d) 最后就变成 d(a, b),d(c, b) (即 d(b, b)), d(a, d)三个,再根据第二种方案,答案就变成了 d(a, b),d(a, d)。
当 d(a, b) < d(c, d) 时,通过第二个简化方案,d(a, b),d(c, d) 最后变成 d(c, d),d(a, d)。
当二者相等时,化简后结果就是 d(a, d)。
综上,所有的化简都会使某个人的关系变成只是借给别人钱或者只是向别人借钱,那么最后的答案就是债主与负债人进行一个匹配就行。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5 + 10;
struct node {
LL k, index;
}a[N], b[N];
struct nd{
LL s, e, to;
}ans[N];
LL n, m, u, v, d, num[N], cnt1, cnt2, sum;
void solve(){
cin >> n >> m;
for (int i = 1; i <= m; i++){
scanf("%lld%lld%lld", &u, &v, &d);
num[u] += d; //向人借钱
num[v] -= d; //借钱给别人
}
for (int i = 1; i <= n; i++){
if (num[i] > 0) a[++cnt1].k = num[i], a[cnt1].index = i; //负债人
else if (num[i] < 0) b[++cnt2].k = -num[i], b[cnt2].index = i; //债主
}
int p = 1, q = 1;
while (p <= cnt1){
LL minn = min(a[p].k, b[q].k);
a[p].k -= minn;
b[q].k -= minn;
ans[++sum].s = a[p].index;
ans[sum].e = b[q].index;
ans[sum].to = minn;
if (a[p].k == 0) p++; //借到了想借的钱
if (b[q].k == 0) q++; //借出了要借的钱
}
cout << sum << "\n";
for (int i = 1; i <= sum; i++)
printf("%lld %lld %lld\n", ans[i].s, ans[i].e, ans[i].to);
}
int main(){
solve();
return 0;
}
标签:int,LL,Debts,CF,num,简化,cnt2,cnt1,1266D 来源: https://www.cnblogs.com/Hamine/p/15786111.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。