zoukankan      html  css  js  c++  java
  • ACWing 240. 食物链 带权并查集

    题目:

    动物王国中有三类动物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句话有的是真的,有的是假的。

    当一句话满足下列三条之一时,这句话就是假话,否则就是真话。

    1) 当前的话与前面的某些真的话冲突,就是假话;
    2) 当前的话中X或Y比N大,就是假话;
    3) 当前的话表示X吃X,就是假话。

    你的任务是根据给定的N和K句话,输出假话的总数。

    输入格式

    第一行是两个整数N和K,以一个空格分隔。

    以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。

    若D=1,则表示X和Y是同类。

    若D=2,则表示X吃Y。

    输出格式

    只有一个整数,表示假话的数目。

    数据范围

    1N500001≤N≤50000,
    0K1000000≤K≤100000

    输入样例:

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

    输出样例:

    3


    刚开始看的时候觉得并查集好像写不了,就是自己憨憨了,实际上就是取模分为三类,这就是通过这些东西的传递性来确定到祖宗的距离,距离可以分为三类(0,1,2)在取模的情况下

    这道题目重点就是想清楚这个取模分类的思路
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 #include <string>
     6 #include <map>
     7 #include <vector>
     8 #include <set>
     9 #include <stack>
    10 
    11 using namespace std;
    12 typedef long long ll;
    13 
    14 const int N  = 5e4 +10;
    15 int p[N],d[N];
    16 int find(int x)
    17 {
    18     if(p[x]!=x)
    19     {
    20         int t = find(p[x]);
    21         d[x] += d[p[x]];//从递归的最低层开始更新距离
    22         p[x] = t;//路径压缩
    23     }
    24     return p[x];
    25 }
    26 int main()
    27 {
    28     int n,k;
    29     cin >> n >> k;
    30     for(int i=0;i<=n;i++)
    31     {
    32         p[i]=i;
    33     }
    34     int a,x,y;
    35     int cun=0;
    36     while(k--)
    37     {
    38         scanf("%d%d%d",&a,&x,&y);
    39         if(x>n||y>n)
    40         {
    41             cun++;
    42         }
    43         else{
    44              if(a==1)
    45             {   
    46                 int px = find(x);
    47                 int py = find(y);
    48                 if(px==py&&(d[x] - d[y])%3)cun++;//判断不是同余的距离就不是同一类
    49                 else if(px != py)
    50                 {
    51                     p[px] = py;
    52                     d[px] = (d[y] - d[x])%3;
    53                 }
    54             }
    55             else {
    56                 int px = find(x);
    57                 int py = find(y);
    58                 if(px==py&&(d[x] - d[y] -1)%3)cun++;//x吃y,就是在取模的情况下 (d[x] - d[y])%3 =1
    59                 else if(px != py)
    60                 {
    61                     p[px] = py;
    62                     d[px] = (d[y] + 1 - d[x])%3;
    63                 }
    64             }
    65         }
    66     }
    67     cout << cun <<endl;
    68 }
    View Code

    emmm,今天是20200202,是一个比较特殊的日子,确定了今天是自己一个人熬夜补题的日子,自己自律,加油,别再不被重视了,最后一年了,再不努力就再也没有机会了。



    你的脸上风淡云轻,谁也不知道你的牙咬得有多紧。你走路带着风,谁也不知道你膝盖上仍有曾摔过的伤的淤青。你笑得没心没肺,没人知道你哭起来只能无声落泪。要让人觉得毫不费力,只能背后极其努力。我们没有改变不了的未来,只有不想改变的过去。
  • 相关阅读:
    c++中关于用stringstream进行的类型转化
    c++中字符串的反转
    搬家
    初次见面,请多关照。
    CCPC2019吉林省赛&&东北地区赛游记
    VS Code下搭建简单的Haskell开发环境
    从零开始的KMP&&AC自动机
    从零开始的LCA(最近公共祖先)
    LuoguP2123 皇后游戏
    LuoguP1080 国王游戏
  • 原文地址:https://www.cnblogs.com/wangzhe52xia/p/12253746.html
Copyright © 2011-2022 走看看