【算法笔记】并查集小结

并查集最朴素的用法就是用来维护连通性。
然后可以用在 Kruskal 算法中求 MST。
并查集还可以维护更多信息~~

1)加上顺序
poj 1456,需要找 1 - i 格子中最靠右的空格。
让每个节点的根代表往左找到的第一个空格。
当一个空格子被占用,维护操作只需要

pa[pos] = pos - 1

PS:这道题也可以不用并查集,用二分来找

2)为点加上权值
zoj 3261
可以看成是 graph and queries 的简化版,在那道题中,需要找联通分量中的第k大,这里只需要维护最大。
所以,让根节点为最大的节点就行了。

3)为边加上权值
边加上权值,边权就相当于 节点和根的函数值,或者说关系。
(其实应该可以用数学语言精炼描述。。无奈。。 = =
不过,可以看下这个描述,我觉得很准确
这一类题,必须首先提起的就是 POJ 1182 食物链,理解此题,这种函数思想就可以入门了。

// POJ 1182 食物链
int pa[N], r[N], n;

void init() {
    memset(r, 0, sizeof(r));
    rep(i, 0, n-1) pa[i] = i;
}

int Find(int x) {
    if ( x == pa[x] ) return x;
    int fa = pa[x];
    pa[x] = Find(pa[x]);
    r[x] = (r[x] + r[fa]) % 3;
    return pa[x];
}

bool unite(int x, int y, int d) {
    int px = Find(x), py = Find(y);
    if ( px == py ) {
        if ( d == 1 ) return r[x] == r[y];
        return ( r[x] - r[y] + 3 ) % 3 == 1;
    }
    pa[px] = py;
    if ( d == 1 ) {
        r[px] = ( r[y] - r[x] + 3 ) % 3;
    } else {
        r[px] = ( r[y] - r[x] + 4 ) % 3;
    }
    return true;
}

例如
POJ 1733 Parity game
f(u, find(u)) = (区间 [1,u] 的1奇偶性)^(区间 [1,find(u)] 的1奇偶性)
hdu 3038 How Many Answers Are Wrong
这道题中还要注意合并的顺序
f(u, find(u)) = (区间 [1,u] 的和)-(区间 [1,find(u)] 的和)

然后就是照单刷一些题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值