标签:
题意:
N个邮件需要鉴别。
两种操作:
1. M X Y:X和Y是同一种邮件
2.S X:X被误判(意味着X要被它从属的那个集合“踢出去"而所有其它的邮件的关系保持不变)
问最后总共有几种邮件。
思路:
用并查集可以实现邮件的“合并”。但是要把单独的X“踢出去”,然后又要保证其它的关系不变。
弄个双层结构,第一层结构是用来描述邮件之前的关系的。第二层结构是用来指向第一层的结点。
第一层是fa,第二层是vfa。当X被“踢出去”时,只要在第一层中新加一个点,然后vfa[x]指向这个新结点即可。
既保留了原来的邮件之前的关系,又顺利地把X“踢出去”了。
代码:
int n,m; int fa[1200005]; int vfa[100005]; int findFa(int x){ return fa[x]==x?fa[x]:fa[x]=findFa(fa[x]); } int main(){ int T=0; while(scanf("%d%d",&n,&m),n||m){ rep(i,1,n){ fa[i]=i; vfa[i]=i; } int cn=n; while(m--){ char ope[5]; scanf("%s",ope); if(ope[0]==‘M‘){ int a,b; scanf("%d%d",&a,&b); int fx=findFa(vfa[a+1]); int fy=findFa(vfa[b+1]); if(fx!=fy){ fa[fx]=fy; } }else{ int x; scanf("%d",&x); vfa[x+1]=++cn; fa[cn]=cn; } } map<int,int> mp; mp.clear(); int ans=0; rep(i,1,n){ int t=findFa(vfa[i]); if(mp[t]==0){ mp[t]=1; ++ans; } } printf("Case #%d: %d\n",++T,ans); } return 0; }
hdu 2473 Junk-Mail Filter(并查集)
标签:
原文地址:http://www.cnblogs.com/fish7/p/4332142.html