[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;
}
posted @ 2025-07-10 20:12  XiaoZi_qwq  阅读(5)  评论(0)    收藏  举报