这里是练习并查集的一些题目和代码:
1.POJ1611
#include
#include
#include
using namespace std;
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){
c=getchar();f=-1;
}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[max(x,y)]=min(x,y);
}
int main(){
int i,j,k,n,m;
while(scanf("%d%d",&n,&m)==2){
if(n==0 && m==0)break;
for(i=0;ifor(i=1;i<=m;i++){
int x,last;
scanf("%d",&k);
for(j=1;j<=k;j++){
scanf("%d",&x);
if(j!=1)join(x,last);
last=x;
}
}
int ans=0;
for(i=0;iif(f[find(i)]==0)ans++;
printf("%d\n",ans);
}
return 0;
}
2.POJ2524
#include
#include
using namespace std;
int f[100010];
int gi() {
char c=getchar();
int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-') {
c=getchar();
f=-1;
}
while(c>='0' && c<='9') {
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x) {
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y) {
x=find(x);
y=find(y);
if(x!=y)f[y]=x;
}
int main() {
int i,j,k,n,m,tail=0;
while(scanf("%d%d",&n,&m)==2){
tail++;
if(n==0 && m==0)break;
for(i=1;i<=n;i++)f[i]=i;
for(i=1;i<=m;i++){
int x=gi(),y=gi();
join(x,y);
}
int ans=0;
for(i=1;i<=n;i++)
if(f[find(i)]==i)ans++;
printf("Case %d: %d\n",tail,ans);
}
return 0;
}
3.HUD1232
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int main(){
int i,j,k,n,m;
while(1){
n=gi();
if(!n)break;m=gi();
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++){
int x=gi(),y=gi();
join(x,y);
}
int ans=0;
for(i=1;i<=n;i++)
if(f[i]==i)ans++;
printf("%d\n",ans-1);
}
return 0;
}
4.村村通
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int main(){
int i,j,k,n,m;
while(1){
n=gi();
if(!n)break;m=gi();
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++){
int x=gi(),y=gi();
join(x,y);
}
int ans=0;
for(i=1;i<=n;i++)
if(f[i]==i)ans++;
printf("%d\n",ans-1);
}
return 0;
}
5.亲戚
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int main(){
int i,j,k,n,m,p;
scanf("%d%d%d",&n,&m,&p);
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++){
int x=gi(),y=gi();
join(x,y);
}
for(i=1;i<=p;i++){
int x=gi(),y=gi();
if(find(x)==find(y))printf("Yes\n");
else printf("No\n");
}
return 0;
}
6.【模板】并查集
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int main(){
int i,j,k,n,m;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++){
int num=gi(),x=gi(),y=gi();
if(num==1)join(x,y);
if(num==2)
if(find(x)==find(y))printf("Y\n");
else printf("N\n");
}
return 0;
}
7.修复公路
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node{
int u,v,w;
}e[100010];
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int cmp(node a,node b){
return a.wint main(){
int i,j,k=0,n,m;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+1,e+m+1,cmp);
int ans=0;
for(i=1;i<=m;i++){
if(find(e[i].u)!=find(e[i].v)){
join(e[i].u,e[i].v);
k++;
ans=max(ans,e[i].w);
}
if(k==n-1)break;
}
if(k==n-1)printf("%d\n",ans);
else printf("-1\n");
return 0;
}
8.畅通工程,不同于HDU1232
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int f[100010];
int gi() {
char c=getchar();
int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-') {
f=-1;
c=getchar();
}
while(c>='0' && c<='9') {
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x) {
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y) {
x=find(x);
y=find(y);
if(x!=y)f[y]=x;
}
int main() {
int i,j,k,n,m;
n=gi();
m=gi();
for(i=1; i<=n; i++)
f[i]=i;
for(i=1; i<=m; i++) {
int x=gi(),y=gi();
join(x,y);
}
int ans=0;
for(i=1; i<=n; i++)
if(f[i]==i)ans++;
printf("%d\n",ans-1);
return 0;
}
9.【SCOI2005】繁忙的城市
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct node{
int u,v,w;
}e[100010];
int f[100010];
int gi(){
char c=getchar();int f=1,sum=0;
while((c>'9' || c<'0') && c!='-')
c=getchar();
if(c=='-'){f=-1;c=getchar();}
while(c>='0' && c<='9'){
sum=sum*10+c-'0';
c=getchar();
}
return f*sum;
}
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
void join(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int cmp(node a,node b){
return a.wint main(){
int i,j,k,n,m;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+1,e+m+1,cmp);
int ans=0;
for(i=1;i<=m;i++)
if(find(e[i].u)!=find(e[i].v)){
join(e[i].u,e[i].v);
ans=max(ans,e[i].w);
}
printf("%d %d\n",n-1,ans);
return 0;
}
10.营救
#include
using namespace std;
int f[100010];
struct node{
int u,v,far;
}e[100010];
int find(int x){
if(f[x]!=x)f[x]=find(f[x]);
return f[x];
}
int cmp(node a,node b){
return a.farjoin(int x,int y){
x=find(x);y=find(y);
if(x!=y)f[y]=x;
}
int main(){
int i,j,k,n,m,s,t;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(i=1;i<=n;i++)
f[i]=i;
for(i=1;i<=m;i++)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].far);
sort(e+1,e+m+1,cmp);
k=0;
int ans=0;
for(i=1;i<=m;i++){
if(find(e[i].u)!=find(e[i].v)){
k++;
join(e[i].u,e[i].v);
ans=max(ans,e[i].far);
}
if(find(s)==find(t))break;
if(k==m-1)break;
}
printf("%d\n",ans);
return 0;
}