• NOIP2023模拟2联测23-害怕


    题目

    对于一个生成树是最小生成树,都有任意的非树边的边权都与其形成环的树边的边权大。

    一种想法是:考虑按输入顺序贪心确定每条边权值,对于一条非树边,记 k k k 为与之形成环的未被确定权值的树边数量,给这 k k k 条边按顺序确定权值,再给这条非树边设权值;对于树边直接赋权值即可。(正确性显然)

    这样做时间复杂度是 O ( n m ) O(nm) O(nm),考虑优化。注意到每次操作时被标记的树边是连续的,所以可以用并查集维护这个连通块深度最小的点,每次像树剖找 LCA 选最深的点往上跳到所在连通块的顶端,直到两个点属于一个连通块为止。由于用了并查集维护,每条边只会走一次,后面又排序,时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn)

    具体实现看代码

    #include
    using namespace std;
    const int N=5e5+1;
    int n,m,f[N],val[N],p[N],ans[N],cnt1;
    int head[N],nxt[N<<1],to[N<<1],w[N<<1],cnt;
    int dep[N],fa[N],sz[N],son[N],top[N];
    struct node
    {
        int u,v,id,type;
    }a[N];
    void add(int u,int v,int W)
    {
        to[++cnt]=v;
        w[cnt]=W;
        nxt[cnt]=head[u];
        head[u]=cnt;
    }
    void dfs(int u,int f)
    {
        fa[u]=f;
        dep[u]=dep[f]+1;
        for(int i=head[u];i;i=nxt[i]){
            if(to[i]!=f){
                val[to[i]]=w[i];
                dfs(to[i],u);
            }
        }
    }
    int find(int x)
    {
        return x==f[x]?x:f[x]=find(f[x]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].type);
            if(a[i].type) add(a[i].u,a[i].v,i),add(a[i].v,a[i].u,i);
        }
        for(int i=1;i<=n;i++) f[i]=i;
        dfs(1,0);
        for(int i=1;i<=m;i++){
            int x=a[i].u,y=a[i].v,cnt=0;
            while(find(x)!=find(y)){
                if(dep[find(x)]<dep[find(y)]) swap(x,y);
                x=find(x);
                f[x]=find(fa[x]);
                p[++cnt]=val[x];
            }
            sort(p+1,p+1+cnt);
            for(int j=1;j<=cnt;j++) ans[p[j]]=++cnt1;
            if(a[i].type==0) ans[i]=++cnt1;
        }
        for(int i=1;i<=m;i++) printf("%d ",ans[i]);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
  • 相关阅读:
    Pyspark图计算:GraphFrames的安装及其常用方法
    app小程序手机端Python爬虫实战11实现自动化登录考研帮app并滑动资讯信息
    【VS Code+Qt6】拖放操作
    用VirtualBox打开VMware创建的虚拟机的方法
    mysql的小数操作
    3. Python 变量和赋值
    vs2022不能加载winform界面
    [Linux] Ansible实操步骤
    基于Springboot实现旧物置换网站平台演示【项目源码+论文说明】分享
    HTML+CSS+JS静态网页设计【二十四节气】期末课程大作业
  • 原文地址:https://blog.csdn.net/dygxczn/article/details/134035874