[SDOI 2008] 洞穴勘测

[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2049

[算法]

LCT动态维护森林连通性

时间复杂度 : O(NlogN ^ 2)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 300010

int n , m;

struct Link_Cut_Tree
{
    struct Node
    {
        int father , son[2];
        bool rev;
    } a[MAXN];
    inline void pushdown(int x)
    {
        if (a[x].rev)
        {
            swap(a[x].son[0] , a[x].son[1]);
            a[a[x].son[0]].rev ^= 1;
            a[a[x].son[1]].rev ^= 1;
            a[x].rev = false;
        }
    }
    inline bool get(int x)
    {
        pushdown(a[x].father);
        return a[a[x].father].son[1] == x;
    }
    inline bool nroot(int x)
    {
        return a[a[x].father].son[0] == x | a[a[x].father].son[1] == x;
    }
    inline void rotate(int x)
    {
        int f = a[x].father , g = a[f].father;
        int tmpx = get(x) , tmpf = get(f);
        int w = a[x].son[tmpx ^ 1];
        if (nroot(f)) a[g].son[tmpf] = x;
        a[x].son[tmpx ^ 1] = f;
        a[f].son[tmpx] = w;
        if (w) a[w].father = f;
        a[f].father = x;
        a[x].father = g;
    }
    inline void splay(int x)
    {
        int y = x , z = 0;
        static int st[MAXN];
        st[++z] = y;
        while (nroot(y))
            st[++z] = y = a[y].father;
        while (z) pushdown(st[z--]);
        while (nroot(x))
        {
            int y = a[x].father , z = a[y].father;
            if (nroot(y))
                rotate((a[y].son[0] == x) ^ (a[z].son[0] == y) ? (y) : (x));
            rotate(x);
        }
    }
    inline void access(int x)
    {
        for (int y = 0; x; x = a[y = x].father)
        {
            splay(x);
            a[x].son[1] = y;
        }
    }
    inline void make_root(int x)
    {
        access(x);
        splay(x);
        a[x].rev ^= 1;
    }
    inline void cut(int x , int y)
    {
        make_root(x);
        if (find_root(y) == x && a[x].father == y && !a[x].son[1])
            a[x].father = a[y].son[0] = 0;
    }
    inline void link(int x , int y)
    {
        make_root(x);
        if (find_root(y) != x) a[x].father = y;
    }
    inline int find_root(int x)
    {
        access(x);
        splay(x);
        while (a[x].son[0])
        {
            pushdown(x);
            x = a[x].son[0];
        }
        return x;
    }
} LCT;

int main()
{

    scanf("%d%d" , &n , &m);
    for (int i = 1; i <= m; i++)
    {
        char type[10];
        scanf("%s" , &type);
        if (type[0] == ‘C‘)
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            LCT.link(x , y);
        } else if (type[0] == ‘D‘)
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            LCT.cut(x , y);
        } else
        {
            int x , y;
            scanf("%d%d" , &x , &y);
            if (LCT.find_root(x) == LCT.find_root(y)) printf("Yes\n");
            else printf("No\n");
        }
    }

    return 0;
}

原文地址:https://www.cnblogs.com/evenbao/p/10088932.html

时间: 2024-10-01 12:04:56

[SDOI 2008] 洞穴勘测的相关文章

【LCT】【SDOI 2008】【bzoj 2049】Cave 洞穴勘测

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 4805 Solved: 2139 Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通

[SDOI 2008]Cave 洞穴勘测

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

[BZOJ2049] [CodeVS1839] [SDOI2008] Cave 洞穴勘测 (LCT)

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

[SDOI2008]Cave 洞穴勘测

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

BZOJ 2049([Sdoi2008]Cave 洞穴勘测-LCT)[Template:LCT]

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4809  Solved: 2141 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

【bzoj 2049】Cave 洞穴勘测

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

洞穴勘测(bzoj 2049)

Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接起来,那么这两个洞穴就是连通的,按顺序连接在一起的这些通道则被称之为这两个洞穴之间的一条路径.洞穴都十分坚固无法破坏,然而通道不太稳定,时常因为外界影响而发生改变,比如,根据有关仪器的监测结果,123号洞穴和127号洞穴之间有时会出现一条通

BZOJ 题目2049: [Sdoi2008]Cave 洞穴勘测(link cut tree)

2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 4698  Solved: 2107 [Submit][Status][Discuss] Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可以通过一条或者多条通道按一定顺序连接

SDOI2008Cave 洞穴勘测

无限膜拜CLJ大牛…… 不会动态树的弱弱在CLJ的帮助下AC了此题 我想到了并查集(人人都会想到的吧……囧),但不知道应该如何处理destroy操作…… 其实 make操作的实质就是:把x节点到其所在集合代表元的路上所有有向边都反过来,然后就可以处理本体所需的所有操作了(自己想想为何). 代码: 1 var i,n,m,x,y:longint; 2 ch,cha:char; 3 fa:array[0..210000] of longint; 4 function find(x:longint):