zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    
  • 相关阅读:
    世界上最遥远的距离(泰戈尔)
    肩周炎?
    [转]C#基础概念二十五问
    [转]ASP.NET 2.0的缓存技术简介
    SQL Server 2005下的分页SQL
    [转]基本的缓存类操作封装(抽象类)
    GridView鼠标经过行变色
    推荐一个好用的.NET2.0下的发送EMail的库
    Data Access Application Block for .NET
    Pet Shop 4.0的缓存机制
  • 原文地址:https://www.cnblogs.com/doubest/p/15411351.html
Copyright © 2011-2022 走看看