• 并查集


    明天就要模拟了。所以今晚还是学习一下攒攒人品防止爆零比较好/严肃脸。

    今晚能学完并查集和rmq就好。

    ~~~~~~~我是正经的分割线~~~~~~~

    这就是传说中的并查集

    int pre[1000];

    int find(int x)//找爸爸

    {

      int r = x;

      while(pre[r] != r) r = pre[r];//把自己变成自己爸爸

      int i = x,j;

      while(i != r)//路径压缩,每个人都指向自己祖先

      {

        j =pre[i];//在把i的长辈由爸爸升级成更高级别后用j记录i爸爸的值

        pre[i] = r;//把爸爸直接改成祖先

        i = j;

      }

      return r;

    }

    void join(int x,int y)//可以把两个集合合并的操作

    {

      int fx = find(x),fy = find(y);

      if(fx != fy) pre[fx] = fy;//把你爸爸变成我爸爸的儿子,我们就是一家人了/滑稽

    }

    是不是到这一切都很简单?之后我发现自己又天真了......

    题出现了......

    盆友,听说过食物链吗(此处应有一个尴尬而不失礼貌的微笑)

    动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A 吃 B,B 吃 C,C 吃 A。 现有 N 个动物,以 1 - N 编号。每个动物都是 A,B,C 中的一种,但是我们并不知道 它到底是哪一种。 有人用两种说法对这 N 个动物所构成的食物链关系进行描述: 第一种说法是“1 X Y”,表示 X 和 Y 是同类。 第二种说法是“2 X Y”,表示 X 吃 Y 。 此人对 N 个动物,用上述两种说法,一句接一句地说出 K 句话,这 K 句话有的是真 的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。 • 当前的话与前面的某些真的话冲突,就是假话 • 当前的话中 X 或 Y 比 N 大,就是假话 • 当前的话表示 X 吃 X,就是假话 你的任务是根据给定的 N 和 K 句话,输出假话的总数。

    输入输出格式


    输入格式:


    从 eat.in 中输入数据 第一行两个整数,N,K,表示有 N 个动物,K 句话。 第二行开始每行一句话(按照题目要求,见样例)

    输出格式:


    输出到 eat.out 中 一行,一个整数,表示假话的总数。

    输入输出样例


    输入样例#1:


    100 7 1 101 1 2 1 2 2 2 3 2 3 3 1 1 3 2 3 1 1 5 5

    输出样例#1:


    3

    说明


    1 ≤ N ≤ 5 ∗ 10^4 1 ≤ K ≤ 10^5

    代码:多少人看完都哭了

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    //by zrt
    //problem:
    using namespace std;
    const int inf(0x3f3f3f3f) ;//没有注释因为博主自己也看不懂......
    const double eps(1e-10) ;
    typedef long long LL;
    int n,k;
    int f[50005],d[50005];//fa | dist to fa
    // 0..1..2 //
    int get(int x){
        if(x==f[x]) return x;
        int tmp=get(f[x]);
        d[x]+=d[f[x]];
        d[x]%=3;
        return f[x]=tmp;
    }
    int main(){
        #ifdef LOCAL
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
        #endif
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){f[i]=i;}
        int tot=0;
        for(int i=0,D,x,y;i<k;i++){
            scanf("%d%d%d",&D,&x,&y);
            if(x>n||y>n||(D==2&&x==y)){
                tot++;continue;
            }
            if(D==1) {
                if(get(x)==get(y)){
                    if(d[x]!=d[y]) tot++;
                }else{
                    int tmp=get(x);
                    f[get(x)]=y;
                    d[tmp]=(-d[x]+3)%3;
                }
            }else {
                if(get(x)==get(y)){//x-->y
                    if((d[x]-d[y]+3)%3!=1) tot++;
                }else{
                    int tmp=get(x);
                    f[get(x)]=y;
                    d[tmp]=(1-d[x]+3)%3;
                }
            }
        }
        printf("%d\n",tot);
        return 0;
    }
  • 相关阅读:
    TypeScript & JSDoc All In One
    k8s & Docker All In One
    How to custom your own Node.js Docker Image All In One
    rollup & TypeScript & tslib All In One
    Linux file system All In One
    how to use npm delete one history version package All In One
    How to use Web Components in React or Vue All In One
    看了这篇使用 dist 发布 npm 包的文章,我整个人都栓Q 了
    yarn 1.x & yarn 2.x All In One
    python中删除字符串中的指定字符
  • 原文地址:https://www.cnblogs.com/yupeiqi/p/8460115.html
Copyright © 2020-2023  润新知