HDU 1232 (简单并查集)

来源:互联网 发布:海信网络电视机 编辑:程序博客网 时间:2024/05/17 23:40

很直接的并查集,只需要找到有多少根,就是需要修的路。

#include<cstdio>#define Max 1010int root[Max];int union_find(int x){    return x == root[x] ? x : (root[x] = union_find(root[x]));}int main(){//    freopen("in.txt","r",stdin);    int sum,n;    while(scanf("%d",&sum) != EOF && sum != 0){        scanf("%d",&n);        for(int i = 1;i <= sum; i++)            root[i] = i;        int u,v;        for(int i = 0;i < n; i++){            scanf("%d%d",&u,&v);            int _u = union_find(u);            int _v = union_find(v);            if(_u != _v)                root[_u] = _v;        }        int ans = -1;        for(int i = 1;i <= sum; i++)            if(root[i] == i)                ans++;        printf("%d\n",ans);    }    return 0;}

并查集:查找和合并。

分开写更直观。

#include<cstdio>#define Max 1010int root[Max];int Find(int x){    while(x != root[x])        x = root[x];    return x;}void Union(int x,int y){    int _u = Find(x);    int _v = Find(y);    if(_u != _v)        root[_u] = _v;}int main(){//    freopen("in.txt","r",stdin);    int sum,n;    while(scanf("%d",&sum) != EOF && sum != 0){        scanf("%d",&n);        for(int i = 1;i <= sum; i++)            root[i] = i;        int u,v;        for(int i = 0;i < n; i++){            scanf("%d%d",&u,&v);            Union(u,v);        }        int ans = -1;        for(int i = 1;i <= sum; i++)            if(root[i] == i)                ans++;        printf("%d\n",ans);    }    return 0;}

当然,在合并的时候不知道,那个根所在的树的节点多,所以要优化。
但是时间上并没有变化,不知道为什么。

#include<cstdio>#include<cstring>#define Max 1010int root[Max];int sum[Max];int visit[Max];int Find(int x){    while(x != root[x])        x = root[x];    return x;}void Union(int x,int y){    int _u = Find(x);    if(visit[x] == 0)        sum[_u]++;    int _v = Find(y);    if(visit[x] == 0)        sum[_v]++;    if(_u != _v){        if(sum[_v] > sum[_u]){            root[_u] = _v;            sum[_v] += sum[_u];        }        else {            root[_v] = _u;            sum[_u] += sum[_v];        }    }}int main(){//    freopen("in.txt","r",stdin);    int s,n;    while(scanf("%d",&s) != EOF && s != 0){        memset(visit,0,sizeof(visit));        memset(sum,0,sizeof(sum));        scanf("%d",&n);        for(int i = 1;i <= s; i++)            root[i] = i;        int u,v;        for(int i = 0;i < n; i++){            scanf("%d%d",&u,&v);            visit[u] = true;            visit[v] = true;            Union(u,v);        }        int ans = -1;        for(int i = 1;i <= s; i++)            if(root[i] == i)                ans++;        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击