Recommendations
题目链接
https://codeforces.com/contest/1315/problem/D
题目大意
给n个点,每个点有一个只a[i]和 使a[i]+1 所需要的价值b[i],考虑使得所有的a[i]都不相同所需要的最小价值
解题思路
考虑使用并查集来求解,一开始假设所有的顶点都指向自己,当我们查找完一个顶点x的时候,就将其与x+1表示x已经存在,在下次+1的时候要至少加到x+1。但是同时需要使总价值最小,我们都知道并查集的链会越加越长,因此我们应按照所需价值从小到大排序,这样最后的价值就是最小的
AC code
#include <bits/stdc++.h> #pragma GCC optimize(2) #define here cout<<"?"<<endl; using namespace std; typedef long long ll; const int maxn=2e5+10; char s[maxn]; inline ll read(){ ll s=0,w=1;char ch = getchar(); while(ch<48 || ch>57) { if(ch=='-') w=-1;ch = getchar(); } while(ch>=48&&ch<=57) s = (s<<1) + (s<<3) + (ch^48),ch=getchar(); return s*w; } map<ll,ll>pre; struct no{ ll id; ll time; }node[maxn]; bool cmp(no a,no b) { if(a.time==b.time) return a.id<b.id; else return a.time>b.time; } int find(int x) { if(pre[x]==0) return x; else return pre[x]=find(pre[x]); } void unite(int x,int y) { x=find(x);y=find(y);if(x!=y) pre[x]=y; } int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>node[i].id; // pre[i]=i; } for(int i=1;i<=n;i++) { cin>>node[i].time; } ll ans=0; sort(node+1,node+1+n,cmp); for(int i=1;i<=n;i++) { ll x=find(node[i].id); ans+=(x-node[i].id)*node[i].time; unite(x,x+1); } cout<<ans<<endl; return 0; }