洛谷 - P5429 - Fence Planning - 并查集

时间:2019-06-12
本文章向大家介绍洛谷 - P5429 - Fence Planning - 并查集,主要包括洛谷 - P5429 - Fence Planning - 并查集使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

https://www.luogu.org/problemnew/show/P5429
很明显是要维护整个连通块的共同性质,并查集一搞就完事了。

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

const int MAXN=100000;

int par[MAXN+5];
int u[MAXN+5],d[MAXN+5],l[MAXN+5],r[MAXN+5];

void init(int n) {
    for(int i=1; i<=n; i++) {
        par[i]=i;
    }
}

int find_par(int x) {
    int k,pk,r;
    r=x;
    while(r!=par[r])
        r=par[r];       //x查到根,保存为r
    k=x;
    while(k!=r) {       //循环处理x的祖先直到根
        pk=par[k];      //保存k的父亲后把k接入r
        par[k]=r;
        k=pk;           //处理k的父亲
    }
    return r;
}

bool union_set(int x,int y) {
    int fx=find_par(x);
    int fy=find_par(y);
    if(fx==fy) {
        return false;
    } else {
        par[fy]=fx;
        u[fx]=max(u[fx],u[fy]);
        d[fx]=min(d[fx],d[fy]);
        l[fx]=min(l[fx],l[fy]);
        r[fx]=max(r[fx],r[fy]);
        return true;
    }
}

ll calc(int fi){
    ll dy=u[fi]-d[fi];
    ll dx=r[fi]-l[fi];
    return 2ll*(dy+dx);
}

int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
#endif // Yinku
    int n,m;
    scanf("%d%d",&n,&m);
    init(n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&l[i],&d[i]);
        r[i]=l[i],u[i]=d[i];
    }
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        union_set(x,y);
    }

    ll ans=1e18;
    for(int i=1;i<=n;i++){
        int fi=find_par(i);
        ans=min(ans,calc(fi));
    }
    printf("%lld\n",ans);

    return 0;
}

原文地址:https://www.cnblogs.com/Yinku/p/11011675.html