HDU 2473 Junk-Mail Filter

来源:互联网 发布:js得到div高度和宽度 编辑:程序博客网 时间:2024/06/05 00:33

带删除操作的并查集,在于并查集各种操作的深入了解,由于存在删除操作,为了使删除操作简单需要在初始化的时候对每个相应的节点创建一个相应的虚拟父节点,然后删除的操作的时候总是删除相应的子节点,是删除操作变的简单,期初自己是对每个父节点利用set维护其相应的子节点,让后在合并和删除的时候进行相应的维护,想法很正确但是代码提交后栈溢出,没找到错在哪了,于是果断采用的别的方法进行求解~~~


STACK_OVERFLOW代码:(恳请大牛指出错误的原因)


/*typedef set<int>::iterator Iter;const int MAXN = 200010;set<int> G[MAXN];int parent[MAXN];void init_set(){    for(int i = 0; i < MAXN; ++i)        G[i].clear();    memset(parent, -1, sizeof(parent));}int find_set(int u){    return parent[u] < 0 ? u : parent[u] = find_set(parent[u]);}void union_set(int u, int v){    int r1 = find_set(u), r2 = find_set(v);    //printf("TTest: %d %d %d %d\n", u, r1, v, r2);    if(r1 != r2)    {        if(parent[r2] < parent[r1])        {            parent[r2] += parent[r1];            parent[r1] = r2;            for(Iter iter = G[r1].begin(); iter != G[r1].end(); ++iter)            {                find_set(*iter);                G[r2].insert(*iter);            }            G[r1].clear();        }        else        {            parent[r1] += parent[r2];            parent[r2] = r1;            for(Iter iter = G[r2].begin(); iter != G[r2].end(); ++iter)            {                find_set(*iter);                G[r1].insert(*iter);            }            G[r2].clear();        }    }    return ;}int main(){    //freopen("aa.in", "r", stdin);        int n, m; int kcase = 0; char op; int u, v;    while(scanf("%d %d", &n, &m) && n+m)    {        kcase++;        init_set();        for(int i = 1; i <= n; ++i)        {            parent[i] = n + i;            parent[n+i] = -2;            G[n+i].insert(i);        }        while(m--)        {            cin >> op;            if(op == 'M')            {                scanf("%d %d", &u, &v);                u++, v++;                union_set(u, v);            }            else            {                scanf("%d", &u); u++;                int r = find_set(u);                parent[r] += 1;                G[r].erase(u);                 parent[u] = -1;                 G[u].clear();                 G[u].insert(u);            }            //for(int i = 1; i <= 2*n; ++i)                //printf("%d ", parent[i]);            //printf("\n");        }        int ans = 0;        for(int i = 1; i <= n; ++i)        {            if(parent[i] < 0)                ans++;            if(parent[n+i] < -1)                ans++;        }        printf("Case #%d: %d\n", kcase, ans);    }    return 0;}*/

AC代码:

int parent[1200010];int belong[100010];void init_set(){    memset(parent, -1, sizeof(parent));}int find_set(int u){    return parent[u] < 0 ? u : parent[u] = find_set(parent[u]);}void union_set(int u, int v){    int r1 = find_set(u), r2 = find_set(v);        if(r1 != r2)    {        if(parent[r2] < parent[r1])        {            parent[r2] += parent[r1];            parent[r1] = r2;        }        else        {            parent[r1] += parent[r2];            parent[r2] = r1;        }    }        return ;}int main(){    //freopen("aa.in", "r", stdin);            int n, m, u, v, cur_p, kcase = 0;    char op;        while(scanf("%d %d", &n, &m) && n+m)    {        kcase++; cur_p = n + n + 1;        for(int i = 1; i <= n; ++i)            parent[i] = n + i;        for(int i = n + 1; i <= n + n + m; ++i)            parent[i] = -1;                    while(m--)        {            //op = getchar();            //cin >> op;            //scanf("%c ", &op);            cin >> op;            if(op == 'M')            {                scanf("%d %d", &u, &v);                u++, v++;                union_set(u, v);            }            else            {                scanf("%d", &u); u++;                parent[u] = cur_p++;            }        }            for(int i = 1; i <= n; ++i)            belong[i] = find_set(i);        sort(belong + 1, belong + n + 1);        int ans = 0;        for(int i = 1; i <= n; ++i)            if(belong[i] != belong[i-1])                ans++;        printf("Case #%d: %d\n", kcase, ans);    }    return 0;}


原创粉丝点击