HDU 2473 Junk-Mail Filter 并查集
2012-09-03 19:37
309 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2473
题意:
N 是 标号为 0~(N-1)的邮件 M是有M行数据。
第二行开始为数据 当输入为M时之后跟着的两个编号表示这两封邮件都为一种垃圾邮件。
当输入为S时跟着的一个标号表示这封邮件被误判,这不是封垃圾邮件,而之前与这封邮件同时被判为垃圾邮件的那封邮件还是垃圾邮件。
输出为有多少种邮件(垃圾邮件也分很多种)。
坑爹:
1.当要将一封垃圾邮件变为普通邮件时,如果在这个垃圾邮件的树中作为根的话,那么变为普通邮件时要将剩余的垃圾邮件重新合并起来。
2.当要搜索有多少个集合(邮件种类)的时候要查找 father[i] == i 这种有多少个,但如果是 (0-1-2-3-4)(假设根为0),将01234这些点都删除了,
用 father[i] == i 来找集合的话会把前面的 (0邮件)也会算上的。
解法:
用一个代理的数组(起始跟输入的值一样),访问、删除的时候将real数组的值改变就行了(删除就将real[i]等于代理数组下标为n以后的位置),而合并就用代理数
组进行操作就行了。
View Code
题意:
N 是 标号为 0~(N-1)的邮件 M是有M行数据。
第二行开始为数据 当输入为M时之后跟着的两个编号表示这两封邮件都为一种垃圾邮件。
当输入为S时跟着的一个标号表示这封邮件被误判,这不是封垃圾邮件,而之前与这封邮件同时被判为垃圾邮件的那封邮件还是垃圾邮件。
输出为有多少种邮件(垃圾邮件也分很多种)。
坑爹:
1.当要将一封垃圾邮件变为普通邮件时,如果在这个垃圾邮件的树中作为根的话,那么变为普通邮件时要将剩余的垃圾邮件重新合并起来。
2.当要搜索有多少个集合(邮件种类)的时候要查找 father[i] == i 这种有多少个,但如果是 (0-1-2-3-4)(假设根为0),将01234这些点都删除了,
用 father[i] == i 来找集合的话会把前面的 (0邮件)也会算上的。
解法:
用一个代理的数组(起始跟输入的值一样),访问、删除的时候将real数组的值改变就行了(删除就将real[i]等于代理数组下标为n以后的位置),而合并就用代理数
组进行操作就行了。
View Code
#include<iostream> using namespace std; const int maxn = 1000000 + 100000 +10; int real[maxn]; int father[maxn]; //father[x]表示x的父节点 int rank[maxn]; //rank[x] 秩,表示x节点所在树的深度 int save[maxn]; int used[maxn]; void Make_Set() { memset(used,0,sizeof(used)); for(int i=0;i<maxn;i++) { father[i]=i; //初始化一开始每个节点的父节点都为本身 rank[i]=1; //初始化一开始每棵树的深度为1 } } int findroot (int a )// 寻找x元素所在的集合也就是找子节点的根节点 { int k=0; while ( a != father[a] ) { save[k++] = a; a = father[a]; } for(int i=0;i<k;i++) father[ save[i] ] = a; return a; } void Union(int x,int y) //合并两个不相交的集合,x,y分别为两个不同的集合 { x = findroot(x); y = findroot(y); if(x != y) { if(rank[x] > rank[y]) //如果x树的深度比y树深,y树接到x树 { father[y] = x; } else if(rank[x] < rank[y]) { father[x] = y; } else if(rank[x] ==rank[y]) //若两树的深度一样 { father[x] = y; //则x树接到y树 rank[y]++; //此时y树的深度+1 } } } int main() { int N; int M; int k = 1; while(cin>>N>>M,N+M) { Make_Set(); int i; for(i =0; i<N;i++) // 让real 和 father 一一对应 { real[i] = i; } int count = N - 1; // 要删除结点时在father数组中的最后一位给real[del]一个新的代理 while(M-- ) { char ch; cin>>ch; if(ch == 'M') { int x; int y; cin>>x>>y; Union(real[x],real[y]); } if(ch == 'S') { int del; cin>>del; real[del] = ++count ; } } int rootcount = 0; //int max = N; /*if(count > N - 1) { max = count; }*/ for(i =0; i<N; i++) { int a=findroot(real[i]); if(!used[a]) { //printf("%d***\n",a); used[a]=1; rootcount++; } } cout<<"Case #"<<k++<<": "<<rootcount<<endl; } return 0; }
相关文章推荐
- HDU 2473 Junk-Mail Filter(并查集)
- hdu 2473 Junk-Mail Filter(并查集的删除操作)
- HDU 2473 Junk-Mail Filter (并查集的删除操作)
- HDU-2473 Junk-Mail Filter(并查集的删除)
- HDU 2473 Junk-Mail Filter 删点并查集
- HDU 2473 Junk-Mail Filter(并查集删点)
- hdu 2473 Junk-Mail Filter 并查集
- HDU 2473 Junk-Mail Filter 【并查集+设立虚父节点(马甲)】
- hdu 2473 Junk-Mail Filter(并查集(虚拟父节点))
- hdu 2473 Junk-Mail Filter 并查集
- HDU-2473-Junk-Mail Filter-并查集的删除操作
- Hdu 2473 Junk-Mail Filter (并查集的删除)
- hdu 2473 Junk-Mail Filter【并查集好题、建立虚拟节点】
- 并查集的删除—hdu 2473 Junk-Mail Filter
- (step5.1.2)hdu 2473(Junk-Mail Filter——并查集)
- HDU-2473 Junk-Mail Filter 并查集的删除
- HDU 2473-Junk-Mail Filter-并查集删除
- HDU 2473 Junk-Mail Filter 并查集删除(FZU 2155盟国)
- hdu 2473 Junk-Mail Filter (并查集的删除)
- HDU 2473 Junk_Mail Filter(并查集(虚点))