• SP5150 JMFILTER


    直秒并查集。这题的难点就在于怎么删点。如果要删的是叶节点,那还好,直接刨掉即可

    如果是中间节点甚至是根节点,那就不好办了.....

    solution:

    对于独立一个点,我可以用邻接表模拟,然后用并查集维护联通,删点就是普通删点,但是实现难度高,复杂度大,算了,还是想正解吧

    正解:对于一个删了的点,我们打个标记,然后开一个新点表示这个点(居然有点像主席树233.....)

    于是,动态开点并查集诞生了(口胡)

    具体操作在代码里解释

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e6+9;
    int n,m,ans,vis[maxn],fa[maxn],d[maxn],cnt;
    int T;
    int find(int x)//普普通通的并查集
    {
        if(fa[x]==x)
        return x;
        return fa[x]=find(fa[x]);
    }
    void mergy(int x,int y)//普普通通的合并
    {
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy)
        fa[fx]=fy;
    }
    void del()//普普通通的清零(多组数据)
    {
        memset(vis,0,sizeof(vis));
        ans=0;
        n=0,m=0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);//普普通通的输入
        while(n!=0||m!=0)
        {
            T++;//记录组数
            cnt=n;
            for(int i=0;i<n+m;i++)//不太普通的初始化,因为n个点m个操作,极端情况全部都是拆,所以初始化要n+m(提前把动态的点开好)
            {
                fa[i]=i;
            }
            for(int i=0;i<n;i++)
            {
                d[i]=i;//d表示fa里,di代替第i个点
            }
            while(m--)
            {
                char ch;
                cin>>ch;
                if(ch=='M')
                {
                    int x,y;
                    scanf("%d%d",&x,&y);
                    mergy(d[x],d[y]);  //合并新点          
                }
                else
                {
                    int x;
                    scanf("%d",&x);
                    d[x]=++cnt;//动态开点,覆盖掉原点
                }
            }
            for(int i=0;i<n;i++)
            {
                int t=find(d[i]);//统计答案
                if(!vis[t])//桶统计答案
                ans++;
                vis[t]=1;
            }
            printf("Case #%d: %d
    ",T,ans);
            del();
            scanf("%d%d",&n,&m);
        }
        return 0;
    }

    (完)

  • 相关阅读:
    专职DBA-MySQL体系结构与基本管理
    JSON
    MIME类型
    文件上传下载
    response常用的方法
    2020.11.27小记
    HTTP请求状态码
    1561. Maximum Number of Coins You Can Get
    1558. Minimum Numbers of Function Calls to Make Target Array
    1557. Minimum Number of Vertices to Reach All Nodes
  • 原文地址:https://www.cnblogs.com/ajmddzp/p/11372478.html
Copyright © 2020-2023  润新知