[NOI2001] 食物链

[NOI2001] 食物链

题目描述

动物王国中有三类动物 \(A,B,C\),这三类动物的食物链构成了有趣的环形。\(A\)\(B\)\(B\)\(C\)\(C\)\(A\)

现有 \(N\) 个动物,以 \(1 \sim 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\) 句话,输出假话的总数。

输入格式

第一行两个整数,\(N,K\),表示有 \(N\) 个动物,\(K\) 句话。

第二行开始每行一句话(按照题目要求,见样例)

输出格式

一行,一个整数,表示假话的总数。

样例 #1

样例输入 #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\le N\le 5 \times 10^4\)\(1\le K \le 10^5\)

思路

  1. 有三种动物,每种动物就是一个集合
  2. 考虑并查集维护集合的关系
  3. 1~n 集合A, n+1~2n 集合B, 2n+1~3n 集合C
import java.io.*;

public class Main {
    static final int N = 50010;
    static int n, k;
    static int[] p = new int[3 * N];
    static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        n = nextInt();
        k = nextInt();
        int ans = 0;
        for (int i = 1; i <= 3 * n; i++) p[i] = i;
        int z, x, y;
        for(int i = 0; i < k; i++){
            z = nextInt();
            x = nextInt();
            y = nextInt();
            if(x > n || y > n){
                ans++;
                continue;
            }
            if(z == 1){
                if(find(x + n) == find(y) || find(x) == find(y + n)){
                    ans++;
                }else {
                    p[find(x)] = find(y);
                    p[find(x + n)] = find(y + n);
                    p[find(x + 2 * n)] = find(y + 2 * n);
                }
            }else{
                if(find(x) == find(y) || find(x) == find(y + n)){
                    ans++;
                }else {
                    p[find(x + n)] = find(y);
                    p[find(x + 2 * n)] = find(y + n);
                    p[find(x)] = find(y + 2 * n);
                }
            }
        }
        out.println(ans);
        out.flush();
    }

    public static int find(int x) {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    public static int nextInt() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }
}
posted @ 2023-05-18 23:26  乖松鼠  阅读(125)  评论(0)    收藏  举报