題意很好懂,主要是怎樣刪除這個集合的一個點是關鍵;
這裏要借用一個數組dp【i】,每個點i都對應一個數,刪除點i,只是把dp【i】所對應的數改變了m++;依次增大;同時他所對應的節點rank--;
最後看集合的個數主要是看rank有幾個大於0的,
#include"stdio.h"
#include"string.h"
int pre[2000006],dp[2000006];
int rank[2000006],n,m;
int find(int k)
{
if(k!=pre[k])
pre[k]=find(pre[k]);
return pre[k];
}
int main()
{
int i,xx,yy,k=1;
char a[10];
while(scanf("%d%d",&m,&n)!=EOF)
{
if(m==0&&n==0)
break;
for(i=0;i<m;i++)
{
pre[i]=i;
dp[i]=i;
rank[i]=1;
}
while(n--)
{
scanf("%s",a);
if(a[0]=='M')
{
scanf("%d%d",&xx,&yy);
xx=find(dp[xx]);
yy=find(dp[yy]);
if(xx!=yy)
{
pre[yy]=xx;
rank[xx]+=rank[yy];
rank[yy]=0;
}
}
else
{
scanf("%d",&xx);
yy=find(dp[xx]);
rank[yy]--;
dp[xx]=m;
pre[m]=m;
rank[m]=1;
m++;
}
}
int sum=0;
for(i=0;i<m;i++)
{
if(rank[i]>0)
sum++;
}
printf("Case #%d: %d\n",k++,sum);
}
return 0;
}