A - How Many Tables
#include<iostream>
using namespace std;
const int maxn = 1050;
int set[maxn];
void init_set()
{
for(int i=0;i<=maxn;++i)set[i]=i;
}
int find_set(int x)
{
return x==set[x]?x:find_set(set[x]);
}
void union_set(int x,int y)
{
x=find_set(x);
y=find_set(y);
if(x!=y)set[x]=set[y];
}
int main()
{
int t,n,m,x,y;
cin>>t;
while(t--)
{
cin>>n>>m;
init_set();
for(int i=1;i<=m;++i)
{
cin>>x>>y;
union_set(x,y);
}
int ans=0;
for(int i=1;i<=n;++i)
{
if(set[i]==i)ans++;
}
cout<<ans<<endl;
}
return 0;
}
优化版,降低了树高:
#include<iostream>
using namespace std;
const int maxn = 1050;
int set[maxn],height[maxn];
void init_set()
{
for(int i=0;i<=maxn;++i)
{
set[i]=i;
height[i]=0;
}
}
int find_set(int x)
{
return x==set[x]?x:find_set(set[x]);
}
void union_set(int x,int y)
{
x=find_set(x);
y=find_set(y);
if(height[x]==height[y])
{
height[x]+=1;
set[y]=x;
}
else
{
if(height[x]<height[y])set[x]=y;
else set[y]=x;
}
}
int main()
{
int t,n,m,x,y;
cin>>t;
while(t--)
{
cin>>n>>m;
init_set();
for(int i=1;i<=m;++i)
{
cin>>x>>y;
union_set(x,y);
}
int ans=0;
for(int i=1;i<=n;++i)
{
if(set[i]==i)ans++;
}
cout<<ans<<endl;
}
return 0;
}
路径压缩版本:
#include<iostream>
using namespace std;
const int maxn = 1050;
int set[maxn],height[maxn];
void init_set()
{
for(int i=0;i<=maxn;++i)
{
set[i]=i;
height[i]=0;
}
}
int find_set(int x)
{
if(x!=set[x])set[x]=find_set(set[x]);
return set[x];
}
void union_set(int x,int y)
{
x=find_set(x);
y=find_set(y);
if(height[x]==height[y])
{
height[x]+=1;
set[y]=x;
}
else
{
if(height[x]<height[y])set[x]=y;
else set[y]=x;
}
}
int main()
{
int t,n,m,x,y;
cin>>t;
while(t--)
{
cin>>n>>m;
init_set();
for(int i=1;i<=m;++i)
{
cin>>x>>y;
union_set(x,y);
}
int ans=0;
for(int i=1;i<=n;++i)
{
if(set[i]==i)ans++;
}
cout<<ans<<endl;
}
return 0;
}
非递归写法:
#include<iostream>
using namespace std;
const int maxn = 1050;
int set[maxn],height[maxn];
void init_set()
{
for(int i=0;i<=maxn;++i)
{
set[i]=i;
height[i]=0;
}
}
int find_set(int x)
{
int r=x;
while(set[r]!=r)r=set[r];
int i=x,j;
while(i!=r)
{
j=set[i];set[i]=r;i=j;
}
return set[x];
}
void union_set(int x,int y)
{
x=find_set(x);
y=find_set(y);
if(height[x]==height[y])
{
height[x]+=1;
set[y]=x;
}
else
{
if(height[x]<height[y])set[x]=y;
else set[y]=x;
}
}
int main()
{
int t,n,m,x,y;
cin>>t;
while(t--)
{
cin>>n>>m;
init_set();
for(int i=1;i<=m;++i)
{
cin>>x>>y;
union_set(x,y);
}
int ans=0;
for(int i=1;i<=n;++i)
{
if(set[i]==i)ans++;
}
cout<<ans<<endl;
}
return 0;
}
B - Ubiquitous Religions
真·套板子
#include<iostream>
#define MAX 50003
using namespace std;
int n,m,i,j,index;
int stu[MAX];
int height[MAX];
void intial()
{
for(int i=1;i<=n;++i)
{
stu[i]=i;height[i]=0;
}
}
int find_father(int x)
{
int r=x;
while(stu[r]!=r)r=stu[r];
int i=x,j;
while(i!=r)//路径压缩
{
j=stu[i];stu[i]=r;i=j;
}
return stu[x];
}
void union_stu(int i,int j)
{
i=find_father(i);
j=find_father(j);
if(height[i]==height[j])
{
height[i]+=1;
stu[j]=i;
}
else
{
if(height[i]<height[j])stu[j]=i;
else stu[i]=j;
}
}
int main()
{
while(cin>>n>>m&&(n||m))
{
intial();
index++;
for(int a=0;a<m;++a)
{
cin>>i>>j;
union_stu(i,j);
}
int ans=0;
for(int i=1;i<=n;++i)
{
if(stu[i]==i)ans++;
}
cout<<"Case "<<index<<": "<<ans<<endl;
}
return 0;
}
C - The Suspects
输入变一变的套板子
#include<iostream>
#define MAX 30004
using namespace std;
int n,m,k,j,index;
int stu[MAX];
int height[MAX];
void intial()
{
for(int i=0;i<n;++i)
{
stu[i]=i;height[i]=0;
}
}
int find_father(int x)
{
int r=x;
while(stu[r]!=r)r=stu[r];
int i=x,j;
while(i!=r)//路径压缩
{
j=stu[i];stu[i]=r;i=j;
}
return stu[x];
}
void union_stu(int i,int j)
{
i=find_father(i);
j=find_father(j);
if(height[i]==height[j])
{
height[i]+=1;
stu[j]=i;
}
else
{
if(height[i]<height[j])stu[j]=i;
else stu[i]=j;
}
}
int main()
{
while(cin>>n>>m&&(n||m))
{
intial();
for(int b=0;b<m;++b)
{
cin>>k;//输入这个组的总人数
if(k>1)
{
//先输入一个,后面的都以它为父
int father=0;cin>>father;
for(int a=1;a<k;++a)
{
cin>>j;
union_stu(j,father);
}
}
else
{
int father;cin>>father;
// stu[father]=father;
}
}
int ans=1;
int tag=find_father(0);
for(int i=1;i<n;++i)
{
// cout<<"stu["<<i<<"]="<<stu[i]<<endl;
if(find_father(i)==tag)ans++;
}
cout<<ans<<endl;
}
return 0;
}
来源:https://www.cnblogs.com/chrysanthemum/p/11939216.html