POJ

来源:互联网 发布:声卡机架软件下载 编辑:程序博客网 时间:2024/06/06 06:30

转眼又是一万天没有写题惹,好愧疚,标题里打上自用模板,就是写好惹,自用的啦,不介意取走,也很欢迎修改,但是不接受人身伤害,哼唧,玻璃心。

本题属于并查集中比较简单的。并查集的题目,需要搞明白的就是,什么是结点,哪些节点已在一个集内,什么条件下可以合并就可以了。

题目链接:点击打开链接
本题分析:每次修好的电脑是一个新的结点,遍历其余结点,若距离可以就join一波。

最基本的结点结构:

struct node  {      int pre;      int value;  }p[N];  


初始化操作:

void Init(int n)  {        for(int i=0;i<n;i++)      {          p[i]=i;          rank[i]=1;      }  } 


find操作:

int find(int x)  {      return x == p[x].pre ? x : find(p[x].pre);  }  

带路径压缩的find操作:

int find(int x)                                                                                                         //查找根节点{     int r=x;    while ( pre[r ] != r )                                                                                              //返回根节点 r          r=pre[r ];     int i=x , j ;    while( i != r )                                                                                                        //路径压缩    {         j = pre[ i ]; // 在改变上级之前用临时变量  j 记录下他的值          pre[ i ]= r ; //把上级改为根节点         i=j;    }    return r ;}

join操作:

void join(const node p1, const node p2)  {      int root1, root2;      root1 = find(p1.pre);      root2 = find(p2.pre);      if(root1 != root2)          ifjoin条件)              p[root2].pre = root1;  }  

带按秩合并的join操作:

void join(int x,int y)  {      x=Find(x);      y=Find(y);      if(x==y)return;      if(rank[x]>=rank[y])      {          p[y]=x;          rank[x]=rank[x]+rank[y];      }else      {          p[x]=y;          rank[y]=rank[y]+rank[x];      }  }  




0 0
原创粉丝点击