zoukankan      html  css  js  c++  java
  • 并查集分析+总结

    对于并查集: 很多次都是迷迷糊糊,尤其是对并查集的优化:

    1.路径压缩  2.按秩合并

    对此个人整理了一下:

    对于最基本的并查集建议看看: 

    百度百科:  http://baike.baidu.com/view/521705.htm

    以例题的形式分析,并用算法描述了

    博客园:   对于有点基础的可以参考下,清晰明了

    http://www.cnblogs.com/cherish_yimi/archive/2009/10/11/1580839.html

    对于第二个优化按秩合并的部分处理有点异议:

    if(rank[x] < rank[y])
                  {
                      num[x]=y;
                   
                  }
                  else if(rank[x]> rank[y])
                  {
                      num[y]=x;
                  }
                  else rank[y]++;

    看到很多博客上都是这么写的,就连维基百科上也是这么处理的!

    个人感觉这样会大大使按秩合并的优化打折,这样处理应该比上面的哪个要严谨多了

               if(rank[x] <= rank[y])
                  {
                      num[x]=y;
                      rank[y]+=rank[x];
                  }
                  else if(rank[x]> rank[y])
                  {
                      num[y]=x;
                      rank[x]+=rank[y];
                  }

    而在sdutoj 2391测试  时间只是略快 

    题目推荐:

    poj 1611  The Suspects

    http://poj.org/problem?id=1611

    模版题不解释 

    View Code
    #include<stdio.h>
    #include<string.h>
    #define N 30005
    int num[N];int rank[N];

    int match(int n)
    {
    if(n!=num[n])
    num[n]=match(num[n]);
    return num[n];
    }

    int main()
    {
    int n,m,k;
    while(scanf("%d%d",&n,&m),n+m)
    {
    //memset(rank,1,sizeof(rank));
    for(int i=0;i<=n;i++)
    {
    num[i]=i; rank[i]=1;
    }
    while(m--)
    {

    int a,b,x,y;
    scanf("%d%d",&k,&a);

    for(int i=1;i<k;i++)
    {
    scanf("%d",&b);
    x=match(a);y=match(b);
    if( x!= y )
    {
    if(rank[x] <= rank[y])
    {
    num[x]=y;
    rank[y]+=rank[x];
    }
    else
    {
    num[y]=x;
    rank[x]+=rank[y];
    }

    }
    }
    }
    printf("%d\n",rank[match(0)]);
    }
    }

    sdut 2391  Dark roads

    http://acm.sdut.edu.cn/web/problem.php?action=showproblem&problemid=2391

    View Code
    #include<stdio.h>
    #include<algorithm>
    using namespace std;
    #define N 200005
    int n,m,road;
    struct node
    {
    int s,e,cost;
    }root[N];
    int num[N];
    int cmp(node a,node b)
    {
    return a.cost<b.cost;
    }
    int find(int x)
    {
    if(x!=num[x]) num[x]=find(num[x]);
    return num[x];
    }
    void dijk()
    {
    for(int i=0;i<=n;i++) num[i]=i;
    road=0;
    for(int i=0;i<m;i++)
    {
    int x,y;
    x=find(root[i].s);
    y=find(root[i].e);
    if(x!=y)
    {
    num[x]=y;
    road+=root[i].cost;
    } } }
    int main()
    {
    while(scanf("%d%d",&n,&m),n+m)
    {
    int sum=0;
    for(int i=0;i<m;i++)
    { int x,y,z;
    scanf("%d%d%d",&x,&y,&z);
    root[i].s=x;root[i].e=y;
    root[i].cost=z; sum+=z;
    }
    sort(root,root+m,cmp);
    dijk();
    printf("%d\n",sum-road);
    }
    }


     以上纯属个人见解,望大家批评指正

    Just a little, maybe change the world
  • 相关阅读:
    正则表达式
    Event flow(事件流)
    Regular Expression(验证账号密码邮箱身份证)
    constructor&object 的联系与区别
    BMAP
    for each in 与for in与for of
    History of program
    脑图(作业)
    对DOM的认识
    BOM的认识
  • 原文地址:https://www.cnblogs.com/skyming/p/2377700.html
Copyright © 2011-2022 走看看