[CCO 2017] 专业网络 解题报告
题目描述
看到“已有若干个就改变权值”,就应该想到贪心。
按价值从大到小处理,每个点都尝试塞入 \(a_i+1\) 及之后的位置,如果不能那就只好买下并放到最前面。
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define For(i,s,t) for(int i=s;i<=t;i++)
#define Down(i,s,t) for(int i=s;i>=t;i--)
#define ls (i<<1)
#define rs (i<<1|1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
inline int min(int x,int y){return x<y?x:y;}
inline int max(int x,int y){return x>y?x:y;}
inline int read(){
register int x=0;
char c=getchar();
while(c<'0' || '9'<c) c=getchar();
while('0'<=c && c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
return x;
}
void write(int x){
if(x>=10) write(x/10);
putchar(x%10+'0');
}
const int N=2e5+1000;
int n,f[N],ans;
int find(int x){return f[x]=(f[x]==x)?x:find(f[x]);}
void Union(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy) return;
f[fx]=fy;
}
struct Node{int a,b;}a[N];
bool cmp(Node x,Node y){return x.b>y.b;}
int main()
{
//freopen("net.in","r",stdin);
//freopen("net.out","w",stdout);
n=read();
For(i,1,n) a[i].a=read(),a[i].b=read();
For(i,1,n) f[i]=i;
sort(a+1,a+n+1,cmp);
For(i,1,n){
int nxt=find(a[i].a+1);
if(nxt==find(n+1)) ans+=a[i].b,nxt=find(1);
//printf("%d\n",nxt);
Union(nxt,nxt+1);
}
printf("%d",ans);
return 0;
}