AcWing 240. 食物链(并查集)

题目链接:https://www.acwing.com/problem/content/description/242/

题解:
见代码详细注释

AC代码:

import java.util.*;

public class Main {
    static int N = (int) 5e4 + 10;
    static int[] p = new int[N];
    
    // d表示到父节点的距离,但是路径压缩之后,d可以表示到根节点的距离
    // 对到根节点的距离求模,得到0,1,2三个值,0代表与根节点同类,1代表吃根节点,2代表被根节点吃
    static int[] d = new int[N]; 
    
    static int find(int x) {
        if (p[x] != x) {
            int t = find(p[x]); // t代表根节点
            d[x] = d[x] + d[p[x]]; // 此时d[p[x]]已经代表父节点到根节点的距离,d[x]经过更新也是到根节点的距离
            p[x] = t; // 此时再将x的父节点指到根节点
        }
        return p[x];
    }
    
    // 一定要用数学求模
    static int mod(int x, int m) {
        return ((x % m) + m) % m;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), k = sc.nextInt();
        int res = 0;
        
        for (int i = 1; i <= n; i ++) p[i] = i; // d[i]默认就为0
        
        while (k -- > 0) {
            int type = sc.nextInt(), x = sc.nextInt(), y = sc.nextInt();
            
            if (x > n || y > n) res ++;
            else {
                int px = find(x), py = find(y);
                
                if (type == 1) {
                    // 这里一定要用数学求模,否则可能有负数存在
                    if (px == py && mod(d[x], 3) != mod(d[y], 3)) res ++;
                    else if (px != py) {
                        p[px] = py;
                        // 要求 d[x] + d[px] == d[y] (% 3),则 d[px] == d[y] - d[x] (% 3)
                        d[px] = (d[y] - d[x]) % 3;
                        // 或者 d[x] + d[px] == d[y] (mod 3),则 d[px] == d[y] - d[x] (mod 3)
                        // 这样做可以保证d[px] >= 0,上面的判断求模可以直接用%
                        // d[px] = mod(d[y] - d[x], 3);
                    }
                }else {
                    // 这里一定要用数学求模,否则可能有负数存在
                    if (px == py && mod(d[y] + 1, 3) != mod(d[x], 3)) res ++;
                    else if (px != py) {
                        p[px] = py;
                        // 要求 d[x] + d[px] == d[y] + 1 (% 3),则 d[px] == d[y] + 1 - d[x] (% 3)
                        d[px] = (d[y] + 1 - d[x]) % 3;
                        // 或者 d[x] + d[px] == d[y] + 1 (mod 3),则 d[px] == d[y] + 1 - d[x] (mod 3)
                        // 这样做可以保证d[px] >= 0,上面的判断求模可以直接用%
                        // d[px] = mod(d[y] + 1- d[x], 3);
                    }
                }
            }
            
        }
        
        System.out.println(res);
    }
}
上一篇:逗号运算符


下一篇:启明云端分享:S系列1.54寸串口屏重磅来袭