并查集

来源:互联网 发布:vb cstr函数 编辑:程序博客网 时间:2024/06/16 03:24
#include<iostream>using namespace std;int f[1000]={0},n,m,k,sum=0;//这里是初始化,数组里面存的是自己数组下表的编号void init(){    int i;    for(i=1;i<=n;i++)    {        f[i]=i;    }}//这是找爹的递归函数,不停地找爹,直到找到祖宗为止,其实就是找犯罪团伙的最高领导人,“擒贼先擒王”原则int getf(int v){    if(f[v]==v)    {        return v;    }    else    {        //这里是路径压缩,每次在函数返回的时候,顺带把路上遇到的人的"BOSS"改为最后找到的祖宗的编号,        //也就是犯罪团伙的最高领导人编号。这样可以提高找到犯罪团伙的最高领导人(其实就是树的祖先)的速度。        f[v]=getf(f[v]);        return f[v];    }}//这里是合并两子集合的函数void merge(int v,int u){    int t1,t2;    t1=getf(v);    t2=getf(u);    if(t1!=t2)//判断两个节点是否在同一个集合中,即是否为同一个祖先    {        f[t2]=t1;        //“靠左原则”,左边变为右边的BOSS。几把右边的集合,作为左边集合的子集合        //经过路径压缩以后,将分f[u]的根的值也赋值为v的祖先f[t1]。    }}int main(){    int i,x,y;    cin>>n>>m;    init();    for(i=1;i<=m;i++)    {        cin>>x>>y;        merge(x,y);    }    for(i=1;i<=n;i++)    {        if(f[i]==i)        sum++;    }    for(i=1;i<=n;i++)    {        cout<<f[i]<<" ";    }    cout<<endl;    cout<<sum<<endl;    return 0;}/*10 91 23 45 24 62 68 79 71 62 4*/

1 0