zoukankan      html  css  js  c++  java
  • coci2011 debt 还债

    coci2011 debt 还债

    Description

    有N个人,每个人恰好欠另一个人Bi元钱,现在大家都没有钱,政府想要给其中一些人欠,使得大家都不欠别人钱。

    如A欠B 50,B欠C 20,则当政府给A50元时,A会立刻用50还清和B的债务,B也会立刻用20还清和C的债务。

    欠款必须一次还清。如A欠B 50, B欠A50,你不能给A 49元让A还49元给B。

    问政府至少花多少钱?

    Input Format

    第一行 N (2≤N ≤ 200,000) 表示居民数

    接下来N行, 每行有两个数 Ai和 Bi, 表示第i位居民欠编号为Ai的居民Bi元钱 1 ≤ Ai≤ N, Ai ≠ i ) , 1 ≤Bi ≤10,000

    Output Format

    政府至少花多少钱

    Sample Input

    4
    2 100
    1 100
    4 70
    3 70

    Sample Output

    170

    Solution

    若i欠Ai Bi元钱,则让i向Ai连出一条边权为Bi的边,构成几个联通块。
    每个联通块,有且仅有一个环。(由题目所给的“每个人恰好欠另一个人Bi元钱”可得)。

    对于不在环上的点a,用拓扑排序处理 ,若a不足以支付债务则由政府支付。

    对于环上的点b,设环外的居民欠他(S_1)元,环上的居民欠他(S_2)元,他欠别人(P)元。

    则政府需要为环上每个居民支付(max(P-S_1 +S_2,0)​)元钱,使得每个居民收到欠款之后有能力还债,并支付

    所有环上居民中最小的(max(P-S_1,0))使得有一个人能在未接受环上居民还钱的情况下能够还债。

    Code

    #include <cstdio>
    #include <algorithm>
    #define N 200007
    
    inline int read(){
    	int num=0,k=1;char c=getchar();
    	while (c<'0'||c>'9'){if (c=='-')k=-1;c=getchar();}
    	while (c>='0'&&c<='9') num=(num<<1)+(num<<3)+c-48,c=getchar();
    	return num*k;
    }
    
    bool pd[N];
    int n,ans,s,m[N],d[N],To[2][N],stac[N];
    
    inline void dfs(int k,int pre){
    	if (pre){
    		ans+=std::max(0,To[1][k]-pre-m[k]);
    		s=std::min(s,std::max(0,To[1][k]-m[k]));
    	}
    	pd[k]=true;
    	if (!pd[To[0][k]]) dfs(To[0][k],To[1][k]);
        else {
        	pre=To[1][k],k=To[0][k];
     		ans+=std::max(0,To[1][k]-pre-m[k]);
    		s=std::min(s,std::max(0,To[1][k]-m[k]));
        }
    }
    
    int main(){
    	n=read();
    	for (int i=1;i<=n;++i)
    		To[0][i]=read(),To[1][i]=read(),++d[To[0][i]];
    	for (int i=1;i<=n;++i)
    		if (!d[i]) stac[++stac[0]]=i;
    	while (stac[0]){
    		int Top=stac[stac[0]--];
    		pd[Top]=true;
    		--d[To[0][Top]];
    		ans+=std::max(To[1][Top]-m[Top],0);
    		m[To[0][Top]]+=To[1][Top];
    		if (!d[To[0][Top]]) stac[++stac[0]]=To[0][Top];
    	}
    	for (int i=1;i<=n;++i)
    		if (!pd[i])
    			s=100007,dfs(i,0),ans+=s;
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    python 结巴分词简介以及操作
    JWT(Json web token)简介
    为什么推荐前端使用Vue.js
    Vue 加载外部js文件
    Docker简介以及操作
    'QueryDict' object is not callable 错误解析
    django- Vue.js 操作
    django —— KindEditor
    websocket ----简介,以及demo
    python --商品评价---- 数据表结构以及理解
  • 原文地址:https://www.cnblogs.com/hyheng/p/7763771.html
Copyright © 2011-2022 走看看