HDU 2473 Junk-Mail Filter (删点并查集)

来源:互联网 发布:电脑网络查询 编辑:程序博客网 时间:2024/06/07 07:13

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2473


题意:给n个点,m个操作,操作分两种,可以把两点合在同一集合或者把某点从原集合分离出去


思路:并查集要增添一个“删除”功能,即保持原树的形态不变,新建一个节点,把要删除的点的信息映射到该点上,之后对此点操作即可


#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <utility>#include <functional>#include <string>#include <set>using namespace std;const int maxn = 2000010;const int mod = 1e9 + 7;const int inf = 0x3f3f3f3f;int fa[maxn], id[maxn];void init(int n){    for (int i = 0; i < n; i++)        fa[i] = id[i] = i;}int find(int x){    return x == fa[x] ? x : fa[x] = find(fa[x]);}void unite(int x, int y){    x = find(x), y = find(y);    if (x != y)        fa[x] = y;}int main(){    int n, m, ca = 1;    while (~scanf("%d%d", &n, &m) && (n + m))    {        init(n);        int cnt = n;        while (m--)        {            char c;            scanf(" %c", &c);            if (c == 'M')            {                int x, y;                scanf("%d%d", &x, &y);                unite(id[x], id[y]);            }            else            {                int x;                scanf("%d", &x);                id[x] = cnt;                fa[cnt] = cnt;                cnt++;            }        }        set <int> s;        for (int i = 0; i < n; i++)            s.insert(find(id[i]));        printf("Case #%d: %d\n", ca++, s.size());    }    return 0;}


0 0