Zoj 3811并查集

来源:互联网 发布:淘宝赚佣金的手机软件 编辑:程序博客网 时间:2024/06/01 10:26

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\n";            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\n";        }        else{            cout<<"Yes\n";        }    }    return 0;}


0 0
原创粉丝点击