Junk-Mail FilterTime Limit: 15000/8000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11601 Accepted Submission(s): 3641 Problem Description Recognizing junk mails is a tough task. The method used here consists of two steps:
Input There are multiple test cases in the input file.
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 |
解析:
并查集的经典题型——删点操作。
具体做法就时最初点的 father 设为
,合并还是照常合并,删点就是再新建一个点,将删的那个点的 father 赋为新建的那个点。比如说 1 2 3 最初的 father 分别为 4 5 6 ,如果合并1 2 3 后共同的 father 为4,这时要删1就将1的 father 设为7,其他2 3 的 father 仍然为4。
代码:
#include <bits/stdc++.h>
using namespace std;
const int Max=1200005;
int t,n,m,x,y,fax,fay,ans,id;
int father[Max],vis[Max];
char ch[2];
inline int get_int()
{
int x=0,f=1;
char c;
for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
if(c=='-') f=-1,c=getchar();
for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
return x*f;
}
inline int get(int v){return father[v]==v ? v : father[v]=get(father[v]);}
int main()
{
while(~scanf("%d%d\n",&n,&m))
{
if(!n && !m) break;
ans=0,id=2*n,t++;
for(int i=1;i<=n;i++) father[i]=i+n;
for(int i=n+1;i<=n*2+m;i++) father[i]=i;
for(int i=1;i<=m;i++)
{
scanf("%s",ch);
if(ch[0]=='M')
{
x=get_int()+1,y=get_int()+1;
if(get(x)!=get(y)) father[get(x)]=get(y);
}
else x=get_int()+1,father[x]=++id;
}
for(int i=n+1;i<=id;i++) vis[i]=0;
for(int i=1;i<=n;i++)
{
int fax=get(i);
if(vis[fax]) continue;
vis[fax]=1,ans++;
}
cout<<"Case #"<<t<<": "<<ans<<"\n";
}
return 0;
}