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

Junk-Mail Filter

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7254    Accepted Submission(s): 2307

Problem Description

Recognizing junk mails is a tough task. The method used here consists of two steps:
1) Extract the common characteristics from the incoming email.
2) Use a filter matching the set of common characteristics extracted to determine whether the email is a spam.

We want to extract the set of common characteristics from the N sample junk emails available at the moment, and thus having a handy data-analyzing tool would be helpful. The tool should support the following kinds of operations:

a) “M X Y”, meaning that we think that the characteristics of spam X and Y are the same. Note that the relationship defined here is transitive, so
relationships (other than the one between X and Y) need to be created if they are not present at the moment.

b) “S X”, meaning that we think spam X had been misidentified. Your tool should remove all relationships that spam X has when this command is received; after that, spam X will become an isolated node in the relationship graph.

Initially no relationships exist between any pair of the junk emails, so the number of distinct characteristics at that time is N.
Please help us keep track of any necessary information to solve our problem.

Input

There are multiple test cases in the input file.
Each test case starts with two integers, N and M (1 ≤ N ≤ 105 , 1 ≤ M ≤ 106), the number of email samples and the number of operations. M lines follow, each line is one of the two formats described above.
Two successive test cases are separated by a blank line. A case with N = 0 and M = 0 indicates the end of the input file, and should not be processed by your program.

Output

For each test case, please print a single integer, the number of distinct common characteristics, to the console. Follow the format as indicated in the sample below.

Sample Input

5 6

M 0 1

M 1 2

M 1 3

S 1

M 1 2

S 3

3 1

M 1 2

0 0

Sample Output

Case #1: 3

Case #2: 2

Source

2008 Asia Regional Hangzhou

题意:有N个点,可以对点进行两种操作,M u v是将点u,v所在的两个集合合并,S u是将点u从其所在的区间内删除,问最后有多少个集合

分析:如果是将两个点所在的集合合并那可以做到,但问题是怎么将这个节点从集合内删除?

可能会想到把根节点指向自己,但是怎么去处理和其他点的关系呢?所以这么做行不通

传统并查集在支持合并的基础上并没有进行将某一个节点从集合内删除的操作,所以要另外想办法,怎么做呢?我们可以设置虚拟节点。

意思就是说如果有一点被删除,可以设置一个新的节点代替它

例如:有4个点{1,2,3,4} 有两个集合A={1,2,3} B={4},如果把A集合的3从集合内除去,那么我们就可以新设置一个节点5来代替节点3,于是就得到A={1,2,3} B={4}

C={5} 以后对于"点3"的操作都对点5进行

用vir[i]数组表示编号为i的节点的实际编号为vir[i],那么Union(vir[u],vir[v])就是把点u所指的点vir[u]和点v所指的点vir[v]进行合并操作,del(u)就是“删除” 集合中的点u,相对来说相当于生成了一个新的节点。

最后集合的个数就是根节点的个数。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<string>
#include<iostream>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<stdlib.h>
#include<algorithm>
#define LL __int64
using namespace std;
const int MAXN=1e6+1e5+5;
int p[MAXN];
int vis[MAXN];
int vir[MAXN]; //存储虚拟点的编号
int n,m,cnt;
int init()
{
    for(int i=0;i<=MAXN;i++) p[i]=i;
    for(int i=0;i<n;i++) vir[i]=i;
    memset(vis,0,sizeof(vis));
    cnt=n;
}
int findfa(int x)
{
    return p[x]==x?x:p[x]=findfa(p[x]);
}
void Union(int u,int v)
{
    int x=findfa(u);
    int y=findfa(v);
    if(x!=y)
        p[x]=y;
}
void del(int u)
{
    vir[u]=cnt++;
}
int main()
{
    freopen("in.txt","r",stdin);
    int Case=0;
    while(scanf("%d %d",&n,&m) && (n||m))
    {
        init();
        while(m--)
        {
            char opt[10];
            scanf("%s",opt);
            if(opt[0]==‘M‘)
            {
                int u,v;
                scanf("%d %d",&u,&v);
                Union(vir[u],vir[v]);
            }
            else
            {
                int u;
                scanf("%d",&u);
                del(u);
            }
        }

        for(int i=0;i<n;i++)
            vis[findfa(vir[i])]=1;

        int ans=0;
        for(int i=0;i<cnt;i++)
            if(vis[i])
                ans++;
        printf("Case #%d: %d\n",++Case,ans);
    }
    return 0;
}

时间: 2024-10-16 15:04:28

HDU 2473 Junk-Mail Filter (并查集节点删除)的相关文章

HDU 3635 延缓更新的并查集

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2839    Accepted Submission(s): 1097 Problem Description Five hundred years later, the number of dragon balls will increase unexpecte

HDU 3461 Code Lock(并查集的应用+快速幂)

* 65536kb,只能开到1.76*10^7大小的数组.而题目的N取到了10^7,我开始做的时候没注意,用了按秩合并,uset+rank达到了2*10^7所以MLE,所以貌似不能用按秩合并. 其实路径压缩也可以不用.............  题目的大意: 一个密码锁上有编号为1到N的N个字母,每个字母可以取26个小写英文字母中的一个.再给你M个区间[L,M],表示该区间的字母可以一起同步"增加"(从'a'变为'b'为增1,'z'增1为'a').假如一组密码按照给定的区间进行有限

HDU 1558 Segment set (并查集+线段非规范相交)

题目链接 题意 : 如果两个线段相交就属于同一集合,查询某条线段所属集合有多少线段,输出. 思路 : 先判断与其他线段是否相交,然后合并. 1 //1558 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <cmath> 6 #define eps 1e-8 7 #define zero(x) (((x) > 0 ? (x) : (-x)) < e

HDU 2473 Junk-Mail Filter (并查集的删除操作)

Problem Description Recognizing junk mails is a tough task. The method used here consists of two steps: 1) Extract the common characteristics from the incoming email. 2) Use a filter matching the set of common characteristics extracted to determine w

hdu 2473 Junk-Mail Filter 并查集删除

点击打开链接 http://acm.hdu.edu.cn/showproblem.php?pid=2473 题意:给出n种操作,M a b表示a和b是同一个并查集,S a表示在并查集中删除a,要注意的是,如果1和2是一个并查集,2和3是一个并查集,那么1和3也是一个并查集,即使删除2之后,我们依然可以得到1和3还是一个集合里的. 思路:由于并查集是一种树结构,无法在树种删除一个点后还让树继续保持着之前的样子,所以我们删除是采取的操作是使用映射,一开始所有点的映射都是自己,然后删除操作就是把这个点

hdu 2473 Junk-Mail Filter (并查集之点的删除)

Junk-Mail Filter Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6276    Accepted Submission(s): 1981 Problem Description Recognizing junk mails is a tough task. The method used here consists o

HDU 2473 Junk-Mail Filter 并查集,虚拟删除操作

给定两种操作 第一种是合并X Y 第二种是把X分离出来,就是从原来的集合中分离出来,其它的关系不变. 关键是怎么分离,可以考虑把它变成一个其它值.HASH[i] = other_val 然后用新值去做并查集即可. 需要注意的一点就是 加入现在根是1,fa[1] = 1, fa[2] = 1, fa[3] = 1 那么如果你删除了1,这应该输出2.但是现在是fa[2] = 1,是一个不存在的根了,这个时候ans应该+1,但是按照并查集的思路 if (find(HASH[i]) == HASH[i]

HDU 3407.Zjnu Stadium 加权并查集

Zjnu Stadium Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3726    Accepted Submission(s): 1415 Problem Description In 12th Zhejiang College Students Games 2007, there was a new stadium built

HDU 1213 How Many Tables (并查集)

How Many Tables Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1213 Appoint description:  System Crawler  (2015-05-25) Description Today is Ignatius' birthday. He invites a lot of friends. Now