• ARC098F Donation


    传送门

    Atcoder

    Solution

    首先是几个引理:

    1. 重新定义权值(val_i=max(a_i-b_i,0)),那么通过这个点必须需要(val_i+b_i)的钱。
    2. 多次经过一个点一定是在最后一次捐赠。
    3. 我们按照(val_i)排序那么大的一定先访问。

    第1个可以感性理解,第2个很显然,这里主要理性证明一下第3个引理:

    设当前钱数为(x),先后经过(i,j)两个站点且(a_i-b_i<a_j-b_j)

    那么两种情况分别对应:

    1. (x ge b_i+a_j)

    2. (x ge b_j+a_i)

    又因为(a_i-b_i<a_j-b_j),所以(a_i+b_j<a_j+b_i)

    所以走下面这种一定更优。

    那么这个时候我们可以根据(val_i)将原图分成多个联通块,联通块内再分就是一棵树是吧(类似淀粉质)。

    在这个树上(dp)即可。

    考虑设(f_i)表示做完以(i)为根的子树的最小钱数,(g_i=f_i-sum_{son in i}b_i)

    我们很显然可以转移(g),然后再用(g)转移(f)即可。

    Code

    /*
      mail: mleautomaton@foxmail.com
      author: MLEAutoMaton
      This Code is made by MLEAutoMaton
    */
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    using namespace std;
    #define ll long long
    #define REP(a,b,c) for(int a=b;a<=c;a++)
    #define re register
    #define int ll
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    inline int gi(){
    	int f=1,sum=0;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    const int N=200010,Inf=1e18+10;
    int n,m,a[N],b[N],sum[N],f[N],p[N],dp[N],vis[N];
    int find(int x){return f[x]!=x?f[x]=find(f[x]):f[x];}
    vector<int>G[N];
    bool cmp(int A,int B){return a[A]<a[B];}
    signed main(){
    	n=gi();m=gi();
    	for(int i=1;i<=n;i++){
    		a[i]=gi();b[i]=gi();a[i]=max(a[i]-b[i],0ll);
    		p[i]=f[i]=i;sum[i]=b[i];dp[i]=a[i];
    	}
    	for(int i=1;i<=m;i++){int u=gi(),v=gi();G[u].push_back(v);G[v].push_back(u);}
    	sort(p+1,p+n+1,cmp);
    	for(int i=1;i<=n;i++){
    		int u=p[i];vis[u]=1;
    		for(int v:G[u])
    			if(vis[v]){
    				int x=find(u),y=find(v);
    				if(x!=y){
    					f[y]=x;sum[x]+=sum[y];
    					dp[x]=min(dp[x],max(dp[y],a[x]-sum[y]));
    				}
    			}
    	}
    	printf("%lld
    ",dp[find(1)]+sum[find(1)]);
    	return 0;
    }
    
  • 相关阅读:
    AJPFX总结hashmap和hashtable的区别
    AJPFX分享JAVA修饰符详解
    AJPFX分享java排序之希尔排序
    Mysql框架---HMySql
    html/css实现聊天布局
    Java连接Mysql
    微信小程序九宫格布局
    Android设计模式——MVP
    iOS与H5交互(WKWbebView)
    iOS MJExtension的使用
  • 原文地址:https://www.cnblogs.com/fexuile/p/11679055.html
Copyright © 2020-2023  润新知