2011暑期集训――并查集解题报告

食物链解题报告-by 0929220010

用一个数组rel[]存储当前结点a 与 父节点fa 的关系

0: 同类

1: fa 吃 a

2:   a 吃 fa

把能确定关系的结点都合并在同一个集合里,而不是把同类的放在同一个集合里。

对任意两个元素 x 与 y ,和 关系 D

Fx=Find(x ); Fy = Find(y );

若Fx == Fy 说明能确定x 与 y 的 关系 ,如图,向量xy=(rel[y]-rel[x]+3)%3 即,x到 y 的关系D-1因满足 等式右边的条件,若不满足,就是假话

 

若Fx != Fy 就要合并

Ani[fy]=fx;

rel[Fy]=(rel[x]+d-1- rel[y]+3)%3 该公式同样是由向量的运算来的

 

在查找一个元素x 时,要压缩路径,此时,要改变rel[x],原来是x 与 父节点 Fx 的 关系 ,现在要改成 x 与 根结点 rx 的关系,同样可以用向量图表示rel[x]=(rel[x]+rel[rx])%3

 

核心代码:

 

for(i=0;i<k;i++)

     {

         scanf("%d%d%d",&d,&a,&b);

         if(a>n || b>n)

              lie++;

         else

         {

              fa=Find(a);  fb=Find(b);

              if(fa!=fb)

                   Merge(a,b,fa,fb,d-1);

              else

              {

                   if((rel[b]-rel[a]+3)%3!=d-1)

                       lie++;

              }

                  

         }

     }

int Find(int x)

{

     int fx=ani[x];

     if(x==ani[x])

         return ani[x];

     ani[x]=Find(ani[x]);

     rel[x]=(rel[x]+rel[fx])%3;

     return ani[x];

}

void Merge(int a,int b,int fa,int fb,int d)

{

     ani[fb]=fa;

     rel[fb]=(rel[a]+d-rel[b]+3)%3;

}

对于几个公式,一开始没明白是怎么出来的,网上说是向量偏移,整理了一下,画了几张图,希望会有帮助。 向量的知识貌似是高中的,都忘光了呢,琢磨了好久,才想起来了一点,呵呵~。因为传图片的事纠结了一小会,谢谢大家,又让我学到了新知识。谢谢...

 

 

 

 


为解题报告打分
暂时不评分

★★
★★★
★★★★
★★★★★
发表您的评论(若贴AC代码或发表禁止言论等违禁行为将被删除并扣除积分)

|返回 |   | 转到页头|
Copyright @ 2008-2024(浙ICP备2022001332号), TZOJ. All Rights Reserved.