欢迎使用CSDN-markdown编辑器

来源:互联网 发布:app读书软件排行 编辑:程序博客网 时间:2024/06/18 11:17

并查集

板子

#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>using namespace std;int father[50002],a,b,m,n,p;int find(int x){if(father[x]!=x)father[x]=find(father[x]);/*x代表例题中的人,father[x]中所存的数代表这一集合中所有人都与一个人有亲戚关系相当于例题中第一个集合所有的元素都与第一个元素有亲戚关系搜索时只要找元素所指向的father[x]=x的元素(即父元素)然后比较两个元素的父元素是否相同就可以判断其关系*/return father[x];}int main(){  int i;  scanf("%d%d%d",&n,&m,&p);  for(i=1;i<=n;i++)    father[i]=i;  for(i=1;i<=m;i++)    {      scanf("%d%d",&a,&b);      a=find(a);      b=find(b);      father[a]=b;    }  for(i=1;i<=p;i++)    {      scanf("%d%d",&a,&b);      a=find(a);      b=find(b);      if(a==b)        printf("Yes\n");      else        printf("No\n");    }  return 0;}

步骤

-每个元素链向自己(初始化)
-根据更多信息修改每个元素链向的对象
-顺带进行路径压缩,每需要指向新根时,先找合并两部分最深的根再合并

poj1611

int main(){    int n = 0,m = 0;    while(1){        cin>>n>>m;        if(n == 0 && m == 0){            break;        }        if(m == 0){            cout<<n<<endl;        }        else{            for(int x = 0;x < n;x ++){                father[x] = x;            }            for(int i = 1;i <= m;i ++){                int k = 0;                int tem = 0;                cin >> k;                cin >> tem;                tem = find(tem);                for(int j = 1;j < k;j ++){                    int a = 0;                    cin >> a;                    int fa = find(a);                    father[fa] = tem;                }            }            int sour = find(0);            int cnt = 0;            for(int i = 0;i < n;i ++){                if(find(i) == sour)                    cnt ++;            }            cout<<cnt<<endl;        }           }    return 0;}

注意

  • tem = find(tem); father[a] = find(father[a]);进行路径优化,以防大量数据执行时递归超时

poj2524

有相同的且还未放在同一集合中的,放到一起并总数减一

#include<iostream>using namespace std;int father[50005] = {0};int find(int a){    if(father[a] != a)        father[a] = find(father[a]);    return father[a];}int main(){    int n = 0,m = 0;    int cse = 1;    while(1){        cin >> n >> m;        if(n == 0 && m == 0){            break;        }        for(int x = 1;x <= n;x ++){            father[x] = x;        }        int cnt = n;        for(int y = 0;y < m;y ++){            int i = 0,j = 0;            cin >> i >> j;            int fi = find(i);            int fj = find(j);            if(fi != fj){                   cnt --;                father[fj] = fi;            }                   }        printf("Case %d: %d\n",cse,cnt);        cse ++;    }}
原创粉丝点击