码迷,mamicode.com
首页 > 其他好文 > 详细

并查集

时间:2014-12-05 22:37:38      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   ar   color   sp   for   on   div   

POJ 1182 食物链

添加一个维护当前节点与父节点关系的信息,每次压缩时更新关系,另外join的时候也要根据当前节点和父节点关系以及两个父节点关系更新;

单case,不用EOF处理。

# include <cstdio>
const int maxn = 50005;
int n, k;
int p[maxn];
int g[maxn];
int find(int x) {
    if (x == p[x]) return x;
    int t = find(p[x]);
    g[x] = ((g[p[x]] + g[x]) % 3 + 3) % 3;
    p[x] = t;
    return t;
}
# define testin freopen("in.txt", "r", stdin)
int main()
{
    //while (scanf("%d%d", &n, &k) != EOF) {
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; ++i) p[i] = i, g[i] = 0;
        int ans = 0;
        for (int i = 0, od, x, y; i < k; ++i) {
            scanf("%d%d%d", &od, &x, &y);
            if (x>n||y>n || (od==2 && x==y)) {
                ++ans;
                continue;
            } else {
                int fx = find(x);
                int fy = find(y);
                if (fx != fy) {
                    p[fx] = fy;
                    g[fx] = ((g[y]-g[x]+od-1)%3+3)%3;
                } else if (((g[x]-g[y])%3+3)%3 != od-1){
                    ++ans;
                }
            }
        }
        printf("%d\n", ans);
    //}

    return 0;
}

 

HDU 2473

带删除节点的并查集

对每个节点,映射射到一个虚拟节点,然后对虚拟节点维护并查集,删除节点时,将对应节点应射到一个新的节点即可,由于查询次数有限,浪费的空间可以接受。

# include <cstdio>
const int maxn = 100005;
const int maxm = 1000005;
int n, m;
int fa[maxn + maxm];
bool isRoot[maxn + maxm];
int link[maxn];
int id;
int find(int x) {
    if (x != fa[x]) return fa[x]=find(fa[x]);
}
void join(int x, int y)
{
    x = find(x);
    y = find(y);
    if (x != y) fa[x] = y;
}
void del(int x)
{
    link[x] = id++;
}
# define testin freopen("in.txt", "r", stdin)
int main()
{
    int ica = 0;
    while (scanf("%d%d", &n, &m), n||m) {
        for (int i = 0; i < n+m; ++i) isRoot[i]=false, fa[i]=i;
        for (int i = 0; i < n; ++i) link[i] = i;
        char od[5];
        id = n;
        for (int i = 0, x, y; i < m; ++i) {
            scanf("%s%d", od, &x);
            if (od[0] == M) {
                scanf("%d", &y);
                join(link[x], link[y]);
            } else {
                del(x);
            }
        }
        int ans = 0;
        for (int i = 0; i < n; ++i) {
            if (!isRoot[ find(link[i]) ]) {
                ++ans;
                isRoot[ find(link[i]) ] = true;
            }
        }
        printf("Case #%d: %d\n", ++ica, ans);
    }
    return 0;
}

 

ZOJ 3261

带删除边的并查集。

WA:维护的并不是树,每个节点和多个节点直接有关系,不能直接删除并查集中的边。

并查集

标签:style   blog   io   ar   color   sp   for   on   div   

原文地址:http://www.cnblogs.com/txd0u/p/4147534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!