• D. Dogeforces 题解(并查集+构造)


    题目链接

    题目大意

    要你构造一棵树

    给你所有树的叶子,数目为n

    并且告诉你所有叶子的lca所代表的权值

    且祖宗节点的权值必定比儿子节点的权值大

    题目思路

    参考代码:https://blog.csdn.net/liufengwei1/article/details/114298063

    就是并查集模拟

    因为祖宗比儿子大,把a\([i][j]\)从小到大排序,然后从下往上构造了,要利用并查集模拟

    而且排序的时候还要按照i排序

    原因

    比如1 2 3 4都是父亲是5,但是你在排序的时候搞出了1 2父亲是5,然后处理3 4,发现他们的父节点都是他们自己,所以搞出个新节点父亲6,最后发现1,3的父亲还是权值和5,6一样,就会出问题,相当于多创建了一个点,但如果一开始排序就先 1 2 ,1 3,1 4,就会只有一个父亲5

    代码

    #include<bits/stdc++.h>
    using namespace std;
    #define fi first
    #define se second
    typedef long long ll;
    typedef pair<double,int> pdi;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int maxn=500+5,mod=1e7;
    int n,m;
    int fa[maxn*maxn];
    int a[maxn][maxn];
    int v[maxn*maxn];
    int c[maxn*maxn];
    struct edge{
        int l,r,val;
    }e[maxn*maxn];
    pair<int,int> ans[maxn*maxn];
    int find(int x){
        return x==fa[x]?x:fa[x]=find(fa[x]);
    }
    bool cmp(edge a,edge b){
        if(a.val!=b.val){
            return a.val<b .val;
        }else {
            return a.l<b.l;
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&a[i][j]);
                e[i+(j-1)*n]={i,j,a[i][j]};
            }
        }
        m=n;
        for(int i=1;i<=n;i++){
            fa[i]=i;
            c[i]=a[i][i];
        }
        sort(e+1,e+1+n*n,cmp);
        int cnt=0;
        for(int i=1;i<=n*n;i++){
            int x=find(e[i].l),y=find(e[i].r);
            if(x==y) continue;
            if(c[x]==e[i].val){
                fa[y]=x;
                ans[++cnt]={y,x};
            }else if(c[y]==e[i].val){
                fa[x]=y;
                ans[++cnt]={x,y};
            }else{
                fa[x]=fa[y]=++m;
                fa[m]=m;
                c[m]=e[i].val;
                ans[++cnt]={x,m};
                ans[++cnt]={y,m};
            }
        }
        printf("%d\n",m);
        for(int i=1;i<=m;i++){
            printf("%d ",c[i]);
        }
        printf("\n%d\n",find(1));
        for(int i=1;i<=cnt;i++){
            printf("%d %d\n",ans[i].fi,ans[i].se);
        }
        return 0;
    }
    
    
    不摆烂了,写题
  • 相关阅读:
    [luoguP2342] 叠积木(并查集)
    [luoguP2147] [SDOI2008]Cave 洞穴勘测(并查集 || lct)
    [POJ1611]The Suspects(并查集)
    [POJ2912]Rochambeau(并查集)
    网站图片增强JS插件2.0(兼容IE&FF)
    jQuery简单纯文字提示条
    复选框--全选/全不选/反选。简易版
    Magic Grid ComboBox JQuery 版
    SWFObject 的基本使用方法
    全局Timestamp管理器 检测js执行时间
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14475065.html
Copyright © 2020-2023  润新知