简单入门并查集, 以前已经做过,但是代码不太好。DP优化搞上火了,做做别的换换脑子...
以前代码
Memory: 356K | Time: 32MS |
usingnamespace std;
const int maxn = 30000;
int father[maxn+5];//记录父节点
int len[maxn+5];//记录以该点为根的集合元素的个数
void init(int n){//并查集的初始化
int i;
for (i=0; i<n; i++)
{
father[i] = i;
len[i] = 1;
}
}
inline int getroot(int x){//获得某节点的根节点(不同于父节点),并压缩路径
int r = x;
while(father[r]!=r)
r = father[r];
while(father[x]!=r){
father[x] = r;
x = father[x];
}
return r;
}
inline void join(int s, int x){//把s和x合并起来
int a = getroot(s);
int b = getroot(x);
if (a!=b){
father[a] = b;
len[b] += len[a];
}
}
int main(){
int n, m, k;
int i, j, x, s;
while(scanf("%d %d", &n, &m)!=EOF){
if (n==0 && m==0) break;
init(n);
for (i=0; i<m; i++){
scanf("%d", &k);
if (k==0) continue;
scanf("%d", &s);
for (j=1; j<k; j++){
scanf("%d", &x);
join(s, x);
}
}
printf("%d\n", len[getroot(0)]);
}
return 0;
}
不用按秩合并的话
Memory: 284K | Time: 16MS |
int p[30005] ;
void make_set(int n){
for(int i=0; i<n; i++)
p[i] = i ;
}
int find_set(int x){
if(x!=p[x])
p[x] = find_set(p[x]) ;
return p[x] ;
}
void union_set(int x, int y){
x = find_set(x) ;
y = find_set(y) ;
if(x!=y)
p[y] = x ;
}
int main(){
int n, m, i, x, y, sum ;
while(~scanf("%d%d", &n, &m)&&(n+m)){
make_set(n) ;
while(m--){
scanf("%d", &i) ;
scanf("%d", &x) ;
i -- ;
while(i--){
scanf("%d", &y) ;
union_set(x, y) ;
}
}
sum = 1 ;
for(i=1; i<n; i++)
if(find_set(i)==find_set(0))
sum ++ ;
printf("%d\n", sum) ;
}
return 0 ;
}
按秩合并
Memory: 400K | Time: 0MS |
int p[30005], r[30005] ;
void make_set(int n){
for(int i=0; i<n; i++){
p[i] = i ;
r[i] = 0 ;
}
}
int find_set(int x){
if(x!=p[x])
p[x] = find_set(p[x]) ;
return p[x] ;
}
void union_set(int x, int y){
x = find_set(x) ;
y = find_set(y) ;
if(x!=y){
if(r[x]>r[y])
p[y] = x ;
else{
p[x] = y ;
if(r[x]==r[y])
r[y] ++ ;
}
}
}
int main(){
int n, m, i, x, y, sum ;
while(~scanf("%d%d", &n, &m)&&(n+m)){
make_set(n) ;
while(m--){
scanf("%d", &i) ;
scanf("%d", &x) ;
i -- ;
while(i--){
scanf("%d", &y) ;
union_set(x, y) ;
}
}
sum = 1 ;
for(i=1; i<n; i++)
if(find_set(i)==find_set(0))
sum ++ ;
printf("%d\n", sum) ;
}
return 0 ;
}