您的位置:首页 > 其它

poj 1611 The Suspects (并查集)

2012-01-30 21:33 281 查看
http://poj.org/problem?id=1611 简单入门并查集, 以前已经做过,但是代码不太好。DP优化搞上火了,做做别的换换脑子...

以前代码

Memory: 356KTime: 32MS
#include<cstdio>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 += 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;
}

不用按秩合并的话

[b]Memory: 284KTime: 16MS
#include<cstdio>
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: 400KTime: 0MS
#include<cstdio> 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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: