zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接

    题目大意

      给你一堆债务关系,债务关系之间可以转移,让你简化债务关系,以使得债务关系中的债务之和最小。

    解题思路

      本来以为必须是本来就存在债务关系的一个集合之间才能互相转移,没想到没关系的也能转移。
      比如说这组数据:

    • 4 2
    • 1 2 12
    • 3 4 8

      就可以转化为:

    • 3 2 8
    • 1 2 4
    • 1 4 8

      好了,现在你读懂题了,应该可以A了吧债务关系的总值之所以能过减少,是因为之前有人借来了某些钱又借了出去,等于说借出去的这波钱倒了好几手,我们对于每个人都统计他借来的钱和借出去的钱,把他们相减就能去掉这些倒来的钱,之后再配对就行了。配对的时候只要保持每个人有借贷关系的人都至少能匹配上一个人并且自己的债务不变就行了。

    代码

    const int maxn = 2e5+10;
    const int maxm = 2e5+10;
    int n, m; 
    ll d[maxn];
    struct I {
    	int x, y; ll w;
    };
    int main() {
    	cin >> n >> m;
    	for (int i = 1, a, b, c; i<=m; ++i) {
    		scanf("%d%d%d", &a, &b, &c);
    		d[a] += c, d[b] -= c;
    	}
    	queue<Pll> a, b;
    	for (int i = 1; i<=n; ++i) {
    		if (d[i]>0) a.push({d[i], i});
    		else if (d[i]<0) b.push({d[i], i});
    	}
    	vector<I> ans;
    	while(!a.empty()) {
    		Pll t1 = a.front(); a.pop();
    		Pll t2 = b.front(); b.pop();
    		ll z = min(t1.x, abs(t2.x));
    		t1.x -= z;
    		t2.x += z;
    		if (t1.x) a.push(t1);
    		if (t2.x) b.push(t2);
    		ans.push_back({t1.y, t2.y, z});
    	}
    	cout << ans.size() << endl;
    	for (int i = 0; i<ans.size(); ++i) printf("%d %d %lld
    ", ans[i].x, ans[i].y, ans[i].w);
    	return 0;
    } 
    
  • 相关阅读:
    Http option 请求是怎么回事
    Azure中配置和发布 Nginx docker到互联网
    Antdesign Form 实现页面控件的赋值加载
    windows下搭建spark+python 开发环境
    Python 使用有道翻译
    Docker安装
    Servlet使用注解配置URl提示404错误
    PowerShell自定义函数定义及调用
    使用代理实现对C# list distinct操作
    Asp.net 按钮幕布遮盖效果实现方式
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14447407.html
Copyright © 2011-2022 走看看