并查集(题解)

这里是练习并查集的一些题目和代码:
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;
}

你可能感兴趣的:(题解,数据结构,题目,题库)