Codeforces 1315D Recommendations

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;
}

 

posted @ 2020-09-27 21:41  mcalex  阅读(125)  评论(0编辑  收藏  举报