Zoj 3811并查集

14年网络赛一道题,有了思路敲起来还是挺流畅了,题目可以理解为不停的添加关键点到图里,然后判断连通性,所以想到了并查集,先把关键点存起来,然后依次进行合并。代码如下,1A还是很高兴的。

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

vector<int> bcj[100005];
vector<int> L;
int in[100005];
int fa[100005];
int n,m,k,l;
int init(){

    for(int i=0;i<=n;i++)
        fa[i]=i;

}
int fin(int x){
    int r=x;
    while(fa[r]!=r){
        r=fa[r];
    }
    return r;
}
void modi(int x,int y){

    int fx=fin(x);
    int fy=fin(y);
    if(fx!=fy){
        if(fx>fy)
            fa[fx]=fy;
        else
            fa[fy]=fx;
    }
}

int main()
{
    int t;
    cin>>t;
    while(t--){
        cin>>n>>m>>k;
        int x;
        L.clear();
        memset(in,0,sizeof(in));
        memset(fa,0,sizeof(fa));
        for(int i=0;i<=n;i++)
            bcj[i].clear();
        for(int i=0;i<k;i++){
            scanf("%d",&x);
            in[x]=1;
        }
        int a,b;
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            bcj[a].push_back(b);
            bcj[b].push_back(a);
        }
        int l;
        cin>>l;
        for(int i=0;i<l;i++){
            scanf("%d",&x);
            L.push_back(x);
        }
        if(l!=k){
            cout<<"No
";
            continue;
        }
        init();
        for(int i=1;i<=n;i++){
            if(in[i]!=1){
                for(int j=0;j<bcj[i].size();j++){
                    if(in[bcj[i][j]]!=1)
                        modi(i,bcj[i][j]);
                }
            }
        }
        in[L[0]]=0;
        for(int i=0;i<bcj[L[0]].size();i++){
            if(in[bcj[L[0]][i]]!=1)
                    modi(L[0],bcj[L[0]][i]);
        }
        int bo=1;
        for(int i=1;i<l;i++){
            in[L[i]]=0;
            for(int j=0;j<bcj[L[i]].size();j++){
                if(in[bcj[L[i]][j]]!=1)
                    modi(L[i],bcj[L[i]][j]);
            }
            if(fin(L[i-1])!=fin(L[i])){
                bo=0;
                break;
            }
        }
        for(int i=1;i<=n;i++){
            fa[i]=fin(i);
        }
        for(int i=2;i<=n;i++){
            if(fa[i]!=fa[i-1]){
                bo=0;
                break;
            }
        }
        if(bo==0){
            cout<<"No
";
        }
        else{
            cout<<"Yes
";
        }

    }
    return 0;
}



原文地址:https://www.cnblogs.com/zhangxianlong/p/10672595.html