• poj1182(并查集)


    题目链接

    分析:根据分析,关系的递推满足由[a,b]~[b,c]得:[a,c]=([a,b]+[b,c])%3;[a,d]=([a,b]+[b,c]+[c,d])%3.由rank数组表示关系

        0 - 这个节点与它的父节点是同类 

        1 - 这个节点被它的父节点吃 

        2 - 这个节点吃它的父节点。 

    则:当 d = 1的时候,( d - 1 ) = 0,也就是我们制定的意义  

         当 d = 2的时候,( d - 1 ) = 1,代表Y被X吃,也是我们指定的意义。

    逆推根节点与Y的关系 

    这部分也是穷举法推出来的,我们举例: 

    父相对于子的relation(即假如子是父的父节点,那么父的relation应该是什么,因为父现在是根节点,所以父.relation = 0,我们只能根据父的子节点反推子跟父节点的关系) 

             0             ( 3 - 0 ) % 3 = 0 

             1(父吃子)   ( 3 - 1 ) % 3 = 2 //父吃子 

             2(子吃父)    ( 3 - 2 ) % 3 = 1 //子吃父,一样的

    因此合并时,x,y,a(x的根节点),b(y的根节点),d(x与y的关系),rank[x](x与a的关系),rank[y](y与b的关系)rank[b](b与a的关系)则:

    [b,a]=([b,y]+[y,x]+[x,a])%3.而[b,y]=(3-[y,b])%3.因此rank[b]=(3-rank[y]+d+rank[x]).

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 100000000
    #define inf 0x3f3f3f3f
    #define eps 1e-9
    #define N 50010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define PII pair<int,int>
    using namespace std;
    int fa[N],rank[N];
    int find(int x)
    {
        if(x==fa[x])return x;
        int pa=fa[x];
        fa[x]=find(fa[x]);
        rank[x]=(rank[x]+rank[pa])%3;
        return fa[x];
    }
    void merge(int a,int b,int x,int y,int d)
    {
        fa[b]=a;
        rank[b]=(3-rank[y]+d-1+rank[x])%3;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
        {
            fa[i]=i;
            rank[i]=0;
        }
        int ans=0;
        while(m--)
        {
            int d,x,y;
            scanf("%d%d%d",&d,&x,&y);
            if(x>n||y>n||(d==2&&x==y))ans++;
            else
            {
                int a=find(x);
                int b=find(y);
                if(a!=b)merge(a,b,x,y,d);
                else
                {
                    if((rank[y]+3-rank[x])%3!=d-1)ans++;
                }
            }
        }
        printf("%d
    ",ans);
    }
    View Code
  • 相关阅读:
    【BZOJ1030】文本生成器
    luogu P1312 Mayan游戏
    luogu P1074 靶形数独
    【题解】 [HNOI2009] 最小圈 (01分数规划,二分答案,负环)
    【题解】 [HEOI2016]排序题解 (二分答案,线段树)
    【题解】 Luogu P1541 乌龟棋总结 (动态规划)
    【题解】Luogu P2047 社交网络总结 (Floyd算法,最短路计数)
    【总结】最短路径条数问题
    第一天进入博客这个神奇的领域 在此%%%erosun
    什么是Kubernetes?
  • 原文地址:https://www.cnblogs.com/lienus/p/4276184.html
Copyright © 2020-2023  润新知