zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第三场)G

    Description

    给定一个 (n) 个点的图,第 (i) 个点一开始是第 (i) 种颜色,接着有 (k) 次操作,第 (i) 次操作指定一个点 (o_i),表示第 (o_i) 种颜色会侵略所有与自己相邻的颜色,求最终每个点的颜色。

    Solution

    任意时刻,每种颜色唯一对应一个连通块

    考虑用并查集维护连通块,其根结点表示颜色

    则只有 (o_i) 是根结点时才可以向外侵略,对于到达的每一个新连通块,将它整个挂在 (o_i) 下即可

    对每个连通块,维护一个生长结点集合,表示从这个连通块一步扩展可以到达的可能属于新连通块的点

    初态下每个连通块的生长结点集合就是它的邻接点

    每次将所有连通块 (q) 并入连通块 (p) 时,(p) 原有的生长结点集合会被丢掉(本次遍历了),新的生长结点集合将由所有的 (q) 的生长结点集合合并而成

    这个过程可以用 vector 启发式合并,也可以用 list.splice 做到线性时间复杂度

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    
    const int N = 1000005;
    
    int t,t1,t2,q,x,n,m,fa[N];
    list<int> g[N];
    
    signed main()
    {
        function<int(int)> find=[&](int x) {return fa[x]==x ? x : fa[x]=find(fa[x]);};
    
        ios::sync_with_stdio(false);
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            for(int i=0;i<n;i++)
            {
                g[i].clear();
                fa[i]=i;
            }
            for(int i=1;i<=m;i++)
            {
                cin>>t1>>t2;
                g[t1].pb(t2);
                g[t2].pb(t1);
            }
            cin>>q;
            while(q--)
            {
                cin>>x;
                int fx=find(x);
                if(x==fx)
                {
                    list<int> res;
                    for(auto i:g[fx])
                    {
                        int q=find(i);
                        if(q!=fx)
                        {
                            fa[q]=fx;
                            res.splice(res.end(), g[q]);
                        }
                    }
                    swap(res, g[fx]);
                }
            }
            for(int i=0;i<n;i++) cout<<find(i)<<" ";
            cout<<endl;
        }
    }
    
    
  • 相关阅读:
    Spring_7_AOP之Advice应用
    JAVA豆知识
    SPRING事务_2
    JSP_5_JavaBean
    Spring事务_1
    java基本类型和包装类型
    SVN使用教程总结
    通过反射来创建对象?getConstructor()和getDeclaredConstructor()区别?
    Java泛型中extends和super的区别?
    数字签名、数字证书、对称加密算法、非对称加密算法、单向加密(散列算法)
  • 原文地址:https://www.cnblogs.com/mollnn/p/13339673.html
Copyright © 2011-2022 走看看