hdu2473 Junk-Mail Filter 并查集的删除

 本题考查的是并查集的删除.

在删除结点的时候要注意这样的问题: 并查集的结构是一棵树,当把某一个结点删去(将其父结点置为自己)时,它的子结点的根就会丢失.因此,在删除某结点的时候,要确定它的所有子结点都已经并到根上了.

解决方法: 为每一个结点加一个虚根,这样每个结点都是叶子结点.插入结点时,把它们都并到虚根的集合中.删除结点时,只要把它的父结点置为一个无用的虚根

http://blog.csdn.net/a181551981/article/details/6286007

#include #include using namespace std; int n,m,a,b,cnt,father[2000000],s[1000041],ans; int find(int x); void merge(int x,int y); //固定根节点,n+1~n+n作为根节点,而1~n作为虚拟根节点(指向n+1~n+n),之后在增添n+n~n+n+m作为备用节点 //删除时直接修改1~n指向的节点到n+n后的节点 int main(){ int Case = 1, n, m, i, a, b, ans; char ch; while(cin>>n>>m && (n||m)) { for(i = 0; i < n; i++) father[i] = i + n; for(i = n; i < n*2+m;i++) father[i] = i; cnt = 2 * n; ans = 0; memset(s, 0, sizeof(s)); while(m--) { cin>>ch; if(ch == 'M') { cin>>a>>b; merge(a, b); } else { cin>>a; father[a] = cnt++; } } for(i = 0; i < n; i++) { int temp = find(i); if(s[temp] == 0) { ans++; s[temp] = 1; } } cout<<"Case #"< y) father[x] = y; }

转载于:https://www.cnblogs.com/windmissing/archive/2012/01/25/2559859.html

你可能感兴趣的:(hdu2473 Junk-Mail Filter 并查集的删除)