食物链题目(带全并查集)

这个题目需要注意好几个地方,最重要的方法就是向量法确定关系转移,而关系转移又需要退到两种情况,第一种,是Find的时候,进行路径压缩的时候,另一种是两个点属于不同的树的时候,而且为了便于操作,我们需要设置0 为 相同(与题目中的关系1相同), 1 为 a吃b(与题目中的关系2对应)。3对应b吃a

代码如下,注意关系,不能随意推到,因为有方向关系:

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std ;
#define MAX 50005

struct Node{
    int f ;
    int r ;
};
int sum ;
Node pre[MAX];
int Find(int x){
   int temp ;
   if(x != pre[x].f )
   {
       temp = pre[x].f;
       pre[x].f = Find(temp);
       pre[x].r = (pre[x].r + pre[temp].r)%3;
   }
   return pre[x].f;
}

int main(){
    sum = 0 ;
    int nums , r_num , R , X,Y;
    cin >> nums >> r_num ;
    for(int i = 0 ; i <=nums ; i ++ )
    {
        pre[i].f= i ;
        pre[i].r =0 ;
    }
    for(int i =  0 ; i < r_num  ; i++ )
    {
        cin >> R >> X >> Y ;
        if(X>nums||Y>nums)
        {
            sum ++ ;
            continue ;
        }
        if(X==Y&&R==2)
        {
            sum ++ ;
            continue ;
        }
        int fx = Find(X);
        int fy = Find(Y);
        if(fx == fy)
        {
            if(R ==1&&pre[X].r != pre[Y].r)
            {
                    sum ++ ;
                    continue ;
            }
            else if(R == 2 &&(3 - pre[Y].r + pre[X].r)%3 != R -1)
            {
                 //此处应为 (3 - pre[Y].r + pre[X].r)%3 != R-1, 因为在合并时是将x合并到y
                    sum ++ ;
                    continue ;
            }
        }else{
            pre[fx].f=fy ;
            pre[fx].r = (3+ R-1 + pre[Y].r - pre[X].r)%3;
        }
    }
    cout << sum <<endl;
    return 0 ;
}

猜你喜欢

转载自blog.csdn.net/qq_36616268/article/details/81193266