• 并查集:POJ 1182 食物链 复习


    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    using namespace std;
    
    const int maxn = 100000*3 + 100;
    int par[maxn];
    int Rank[maxn];
    int N, K;
    int T[maxn], X[maxn], Y[maxn];
    
    //初始化n个元素 
    void init(int n)
    {
        for (int i = 0; i < n; i++)
        {
            par[i] = i;
            Rank[i] = 0;
         } 
    }
    
    //查询树的根
    int Find(int x)
    {
        if (par[x] == x) 
        {
            return x;
        }
        else
        {
            return par[x] = Find(par[x]);
        }
    }
    
    //合并x和y所述的集合 
    void unite(int x, int y)
    {
        x = Find(x);
        y = Find(y);
        if (x == y) return;
        
        if (Rank[x] < Rank[y]) {
            par[x] = y;
        }
        else {
            par[y] = x;
            if (Rank[x] == Rank[y]) Rank[x]++;
        }
    }
    
    bool same(int x, int y)
    {
        return Find(x) == Find(y);
    }
    
    void input()
    {
        scanf("%d%d", &N, &K);
        for (int i = 0; i < K; i++)
        {
            scanf("%d%d%d", &T[i], &X[i], &Y[i]);
        }
    }
    
    void solve()
    {
        input();
        //初始化并查集
        //元素x, x + N, x + 2*N 分别代表 x-A, y-B, x-C
        init(N * 3);
        
        int ans = 0;
        for (int i = 0; i < K; i++)
        {
            int t = T[i];
            int x = X[i] - 1, y = Y[i] - 1;   //把输入变成 0, ... , N-1 范围
            
            //不正确的编号
            if (x < 0 || x >= N || y < 0 || y >= N) 
            {
                ans++;
                continue;
            } 
            
            if (t == 1) 
            {
                //"x和y属于同一类"的信息    
                if (same(x, y + N) || same(x, y + 2*N)) 
                {
                    ans++;
                }
                else 
                {
                    //同属A,或B,或C类 
                    unite(x, y);
                    unite(x + N, y + N);
                    unite(x + 2*N, y + 2*N);
                }
            }
            else {
                //"x吃y"的信息错,同为一类,或者隔了1类  
                if (same(x, y) || same(x, y + 2*N)) {
                    ans++;
                }
                else {
                    unite(x, y + N);          // A -> B
                    unite(x + N, y + 2 * N);  // B -> C
                    unite(x + 2 * N, y);      // C -> A
                }
            } 
        } 
        printf("%d
    ", ans);
    }
    
    int main()
    {
        solve();
        
        return 0;
    }
  • 相关阅读:
    自动获取Xpath、CSS相对路径的Chrome插件
    Appium Desired capabilities详解
    手机自动化录制回放工具SoloPi
    用正交表工具PICT自动设计测试用例
    python循环删除列表元素常见错误与正确方法
    appium微信公众号H5页面自动化测试
    使用fiddler修改请求、响应的数据
    appium inspector抓取元素、录制脚本
    如何更好的设计测试用例
    多数元素-leetcode
  • 原文地址:https://www.cnblogs.com/douzujun/p/8531093.html
Copyright © 2020-2023  润新知