2022 Nioke Winter Holiday Algorithm Basic Training Camp 2、Xiaosha's Magic

ポータルの
ここに画像の説明を挿入
アイデア:

間隔は0から目標値まで増加します。これは間隔目標値の最初のケースに相当し、毎回間隔を-1にし、最後に目標値をすべて0にします。その後、全体的なアイデアは最高点を下げることです。最初に、これまで待ちます。エッジで接続された2つのポイントの高さが同じである場合、それらを接続します。これにより、このエッジの重みとして、両側の2つのポイントの高さが低い方を見つけることができます(高さは下の方に下がります。2つはポイントが接続されている場合)、エッジの重みを大きいものから小さいとトラバースし、トラバーサルプロセス中に接続されたブロックを見つけてマージします(ポイントに抽象化されます。同じ高さであるということ)、重量が大きすぎるので、慎重に

コード:

#include <bits/stdc++.h>
using namespace std;

const int maxn=5000000+50;
int n,m,T,a[maxn],sum[maxn],f[maxn];

struct node{
    
    
    int l,r,w;
}l[maxn];
long long ans;

bool cmp(node x,node y){
    
    
    return x.w>y.w;
}

int find(int x){
    
    
    if (f[x]==x) return x;
    return f[x]=find(f[x]);
}

int main(){
    
    
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; ++i)
        scanf("%d",&a[i]),f[i]=i;
        
    for (int i=1; i<=m; ++i){
    
    
        scanf("%d%d",&l[i].l,&l[i].r);
        l[i].w=min(a[l[i].l],a[l[i].r]);
    }
    sort(l+1,l+m+1,cmp);
    
    for (int i=1; i<=m; ++i){
    
    
        int f1=find(l[i].l),f2=find(l[i].r);
        if (f1==f2) continue;
        
        //各个连通块中非最小值与最小值的差分
        //差就是那个点需要减低到什么时候这条边才能相连
        ans+=max(a[f1],a[f2])-min(a[f1],a[f2]);
        a[f1]=a[f2]=min(a[f1],a[f2]);
        f[f1]=f2;
    }
    for (int i=1; i<=n; ++i)
    	//各个连通块中的最小值
        if (find(i)==i) ans+=a[i];
    printf("%lld\n",ans);
    return 0;
}

おすすめ

転載: blog.csdn.net/qq_45550375/article/details/122738930