HDU2473 Junk-Mail Filter 并查集
欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - HDU2473
题意概括
一堆点。
要你支持合并两组点、分离某组点中的一个,这两种操作。
点数<=100000,操作数<=1000000
题解
删除点不难,只需要把之前那个点不删除,然后再建立一个新的点就可以了。具体直接看代码应该就懂了。
代码
#include <cstring> #include <cstdio> #include <algorithm> #include <cstdlib> #include <cmath> using namespace std; const int N=100005,M=1000005; int Case=0,n,m,fa[N+M],last[N],cnt; int res[N]; int getf(int k){ return fa[k]==k?k:fa[k]=getf(fa[k]); } int main(){ while (~scanf("%d%d",&n,&m)&&(n||m)){ for (int i=1;i<=n;i++) last[i]=fa[i]=i; cnt=n; while (m--){ char op[2]; int a,b; scanf("%s",op); if (op[0]=='M'){ scanf("%d%d",&a,&b); a++,b++; a=getf(last[a]),b=getf(last[b]); fa[a]=b; } else { scanf("%d",&a); a++; last[a]=++cnt; fa[cnt]=cnt; } } for (int i=1;i<=n;i++) res[i]=getf(last[i]); sort(res+1,res+n+1); int ans=1; for (int i=2;i<=n;i++) if (res[i]!=res[i-1]) ans++; printf("Case #%d: %d\n",++Case,ans); } return 0; }