• bzoj4998: 星球联盟


    被gc巨侠D飞来做这题,好恶心,还不让人在线LCT T_T (其实明明就是你忘了强行甩锅)

    xgc:并查集乱搞就能过写什么LCT

    动态维护双联通分量

    我们离线做......

    首先做一次最小生成树,构出搜索树

    然后没有用到的边就拿去暴力合并环,用并查集跳着找

    完了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    struct node
    {
        int x,y,next;
    }a[810000];int len,last[210000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int fa[2][210000];
    int findfa(int x,int w)
    {
        if(fa[w][x]<0)return x;
        fa[w][x]=findfa(fa[w][x],w);return fa[w][x];
    }
    int dep[210000];
    void dfs(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(dep[y]==0)
                dep[y]=dep[x]+1, fa[0][y]=x, dfs(y);
        }
    }
    int Link(int x,int y)
    {
        int fx=findfa(x,1),fy=findfa(y,1);
        if(fx!=fy)
        {
            int tot=0; x=fx,y=fy;
            while(x!=y)
            {
                if(dep[x]<dep[y])swap(x,y);
                tot+=fa[1][x];
                fa[1][x]=findfa(fa[0][x],1);
                x=fa[1][x];
            }
            fa[1][x]+=tot;
        }
        return -fa[1][findfa(x,1)];
    }
    
    struct edge{int x,y;}e[410000];
    bool v[410000];
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        int n,m,Q,x,y;
        scanf("%d%d%d",&n,&m,&Q);
        
        for(int i=1;i<=n;i++)fa[1][i]=-1;
        len=1;memset(last,0,sizeof(last));
        memset(v,false,sizeof(v));
        for(int i=1;i<=m+Q;i++)
        {
            scanf("%d%d",&e[i].x,&e[i].y);
            int fx=findfa(e[i].x,1),fy=findfa(e[i].y,1);
            if(fx!=fy)
            {
                v[i]=true; fa[1][fx]=fy;
                ins(e[i].x,e[i].y), ins(e[i].y,e[i].x);
            }
        }
        
        memset(dep,0,sizeof(dep));
        for(int i=1;i<=n;i++)
            if(dep[i]==0) dep[i]=1, fa[0][i]=0, dfs(i);
            
        for(int i=1;i<=n;i++)fa[1][i]=-1;
        for(int i=1;i<=m+Q;i++)
        {
            if(v[i]==true)
            {
                if(i>m)printf("No
    ");
            }
            else
            {
                int d=Link(e[i].x,e[i].y);
                if(i>m)
                {
                    if(d==-1)printf("No
    ");
                    else printf("%d
    ",d);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    函数声明与函数指针
    【LeetCode】三角形最小路径和
    【LeetCode】字符串中的第一个唯一字符
    【LeetCode】基本计算器II
    【LeetCode】二叉树的最小深度
    【LeetCode】加油站
    java中json与对象的转换
    idea2017 无法使用maven3.6.3版本导入依赖
    springboot项目注册为windows系统服务并设置开机自启
    springmvc上传文件
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9673385.html
Copyright © 2020-2023  润新知