zoukankan      html  css  js  c++  java
  • poj1182 食物链(带权并查集)

    原题链接

    思路:

    看起来并查集似乎不太好下手, 但如果我们拆成几个属性以后就方便合并了

    开三倍n大小的数组, x代表x的种族, x + n代表x的猎物, x + 2 * n代表x的天敌(这里的 猎物/天敌 不仅仅是个体, 而是一个群体)

    如果操作为1 x y的话, 我们就将x跟y合并, x + n跟y + n合并, x + 2 * n跟y + 2 * n合并(同类属性相同)

    如果操作为2 x y的话, 我们就将

    x跟y + 2 * n合并(x是y的天敌),

    x + n跟y合并(x的猎物是y),

    x + 2 * n跟y + n合并(x的天敌是y的猎物, 因为根据题意中的描述, 食物链是一个环, A吃B, B吃C, C吃A)

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <string>
      6 #include <bitset>
      7 #include <vector>
      8 #include <map>
      9 #include <queue>
     10 using namespace std;
     11 typedef long long ll;
     12 
     13 const int MAXN = 5e4 + 7, INF = 0x3f3f3f3f;
     14 int fa[4 * MAXN], ra[4 * MAXN], n, m, cnt;
     15 
     16 inline ll read()
     17 {
     18 
     19     int x = 0, f = 1;
     20     char ch = getchar();
     21     while (ch < '0' || ch > '9')
     22     {
     23         if (ch == '-')
     24             f = -1;
     25         ch = getchar();
     26     }
     27     while (ch >= '0' && ch <= '9')
     28     {
     29         x = x * 10 + ch - '0';
     30         ch = getchar();
     31     }
     32     return x * f;
     33 }
     34 
     35 int find(int x)
     36 {
     37     return x == fa[x] ? x : fa[x] = find(fa[x]);
     38 }
     39 bool unite(int x, int y)
     40 {
     41     x = find(x);
     42     y = find(y);
     43     if (x == y)
     44         return false;
     45     if (ra[x] > ra[y])
     46         swap(x, y);
     47 
     48     fa[y] = x;
     49     if (ra[x] == ra[y])
     50         ra[x]++;
     51     return true;
     52 }
     53 
     54 int main()
     55 {
     56     int ans = 0;
     57     int T, x, y, op;
     58 
     59     n = read();
     60     m = read();
     61     cnt = n;
     62     for (int i = 1; i <= 3 * n; ++i)
     63     {
     64         fa[i] = i;
     65         ra[i] = 1;
     66     }
     67 
     68     for (int i = 0; i < m; ++i)
     69     {
     70         op = read();
     71         x = read();
     72         y = read();
     73         if (x > n || y > n)
     74         {
     75             ++ans;
     76             continue;
     77         }
     78         if (op == 1)
     79         {
     80             if (find(x) == find(y + 2 * n) || find(x + 2 * n) == find(y))
     81             {
     82                 ans++;
     83                 continue;
     84             }
     85             unite(x, y);
     86             unite(x + n, y + n);
     87             unite(x + 2 * n, y + 2 * n);
     88         }
     89         else
     90         {
     91             if (find(x) == find(y) || find(2 * n + x) == find(y))
     92             {
     93                 ans++;
     94                 continue;
     95             }
     96             unite(x, y + 2 * n);
     97             unite(x + n, y);
     98             unite(x + 2 * n, y + n);
     99         }
    100     }
    101     printf("%d
    ", ans);
    102 
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    Wpf 简单制作自己的窗体样式(2)
    Wpf 简单制作自己的窗体样式
    Microsoft Expression Blend 4制作简单的按钮
    Jest和enzyme 前端单元测试工具
    使用socket.io实现多房间通信聊天室
    如何快速开发一个微信小游戏--实例《打气球》
    使用flow来规范javascript的变量类型
    前端开发工具icestar
    vue.js和vue-router和vuex快速上手知识
    react.js插件开发,x-dailog弹窗浮层组件
  • 原文地址:https://www.cnblogs.com/daremo/p/15194392.html
Copyright © 2011-2022 走看看