POJ 并查集

来源:互联网 发布:数据库先学哪个 编辑:程序博客网 时间:2024/05/07 18:20

POJ1308


并查集:判断是否属于同一棵树

数组:记录入度

#include <cstdio>#include <cstdlib>#include <set>#include <iterator>#define MAXN 10001using namespace std;set<int> st;set<int>::iterator it;int father[MAXN];int degree[MAXN];//入度void makeSet(){    for (int i=1; i<MAXN; i++) {        father[i]=i;        degree[i]=0;    }}int findSet(int x){        return x==father[x]?x:father[x]=findSet(father[x]);   /* if (x!=father[x]) {        father[x]=findSet(father[x]);//路径压缩    }    return father[x];*/}void unionSet(int x,int y){    int fx=findSet(x);    int fy=findSet(y);    father[fy]=fx;}int main(){        bool fail;        int k=1;    int a,b;    while (scanf("%d%d",&a,&b)&&(a!=-1&&b!=-1)) {        if (a==0&&b==0) {//空树            printf("Case %d is a tree.\n",k++);            continue;        }        st.clear();//清空                st.insert(a);        st.insert(b);                makeSet();//初始化        unionSet(a, b);                ++degree[b];//入度++                while (scanf("%d%d",&a,&b)&&(a&&b)) {//a,b!=0            st.insert(a);            st.insert(b);            unionSet(a, b);            ++degree[b];        }                int fs=findSet(father[*st.begin()]);        int zeroCnt=0;//统计有多少个入度为0的节点        fail=false;                for (it=st.begin(); it!=st.end(); ++it) {            if (fs!=findSet(father[*it])) {//树中节点的祖先都一样,否则不是树                fail=true;                break;            }            if (degree[*it]>1) {//入度>1不是树                fail=true;                break;            }            if (degree[*it]==0) {//统计根                ++zeroCnt;            }        }                printf("Case %d ",k++);        if (fail||zeroCnt!=1) {//根不是一个            printf("is not a tree.\n");        }else{            printf("is a tree.\n");        }    }        return 0;}


POJ1611

#include <cstdio>#include <iostream>using namespace std;const int MAXN=30001;int fa[MAXN];//父节点int ran[MAXN];int num[MAXN];//节点数void makeSet(int n){    for (int i=0; i<n; i++){        fa[i]=i;        num[i]=1;    }}int findSet(int x){    int r=x;    while (fa[r]!=r) {//find the root        r=fa[r];    }        int t=x;    while (x!=r) {//compress        t=fa[x];        fa[x]=r;        x=t;    }    return r;}void unionSet(int x,int y){    int fx=findSet(x);    int fy=findSet(y);        if (num[fx]>num[fy]) {        fa[fy]=fx;        num[fx]+=num[fy];    }else{        fa[fx]=fy;        num[fy]+=num[fx];    }    }int main(){    int m,n;    while (scanf("%d %d",&n,&m)) {        if (m==0&&n==0) {            break;        }        if (m==0) {//group is 0            printf("1\n");            continue;        }                makeSet(n);//n student                int t;        for (int i=0; i<m; i++) {            scanf("%d",&t);            int ni,nj;            scanf("%d",&ni);            for (int j=1; j<t; j++) {                scanf("%d",&nj);                if (findSet(ni)!=findSet(nj)) {                    unionSet(ni, nj);                }                ni=nj;            }        }                int res=findSet(0);        printf("%d\n",num[res]);    }    return 0;}

POJ2524

#include <cstdio>#include <iostream>using namespace std;const int MAXN=50001;int fa[MAXN];int ran[MAXN];int res;void makeSet(int n){    for (int i=0; i<n; i++) {        fa[i]=i;        ran[i]=1;    }}int findSet(int x){    int r=x;    while (fa[r]!=r){//find the root        r=fa[r];    }    int t=x;    while (x!=r) {//compress        t=fa[x];        fa[x]=r;        x=t;    }    return r;}void unionSet(int x,int y){    int fx=findSet(x);    int fy=findSet(y);    if (ran[x]>ran[y]) {        fa[fy]=fx;    }else{        fa[fx]=fy;        if (ran[fx]==ran[fy]) {            ran[fy]++;        }    }    res--;//kind-1}int main(){        int m,n,k=1;    while (scanf("%d%d",&n,&m)) {        if (n==0&&m==0) {            break;        }                makeSet(n);        res=n;//n kind                int x,y;        for (int i=0; i<m; i++) {            scanf("%d%d",&x,&y);            if (findSet(x)!=findSet(y)) {                unionSet(x, y);            }        }                printf("Case %d: %d\n",k,res);        k++;    }        return 0;}



POJ1182

使用带权值的并查集

#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>using namespace std;const int LYD=50010;//animal number upperstruct Animal{    int num;    int parent;    int relation;//relationship with father node};Animal ani[LYD];int res=0;int findParent(Animal *node){        int tmp;    if (node->parent==node->num) {//root        return node->parent;    }        tmp=node->parent;        //printf("Animal %d s Parent is %d\n",node->num,node->parent);        node->parent=findParent(&ani[node->parent]);    node->relation=(ani[tmp].relation+node->relation)%3;        return node->parent;}void UnionSet(int x,int y,int a,int b,int d){    ani[b].parent=a;    ani[b].relation=((3-ani[y].relation)+(d-1)+ani[x].relation)%3;}void initAnimal(int n){    for (int i=1; i<=n; i++) {        ani[i].num=i;        ani[i].parent=i;        ani[i].relation=0;    }}int main(){        int N,K;    int d,X,Y;        scanf("%d%d",&N,&K);        initAnimal(N);        for (int i=0; i<K; i++) {                scanf("%d%d%d",&d,&X,&Y);                if (X>N||Y>N) {//error case2            res++;        }else{            if (d==2&&X==Y) {//error case3                res++;            }else{                int a=findParent(&ani[X]);                int b=findParent(&ani[Y]);                if (a!=b) {//different set                    UnionSet(X, Y, a, b, d);                }else{//same set                    switch (d) {                        case 1:                            if (ani[X].relation!=ani[Y].relation) {                                res++;                            }                            break;                        case 2:                            if (((ani[Y].relation+3-ani[X].relation)%3)!=1) {                                res++;                            }                            break;                        default:                            break;                    }                }            }        }    }    printf("%d\n",res);    return 0;}


0 0
原创粉丝点击