首页 > 代码库 > [luoguP2024] 食物链(并查集)

[luoguP2024] 食物链(并查集)

传送门

 

经典的并查集问题

对于这种问题,并查集需要分类

开3*n的并查集,其中x用来连接与x同类的,x+n用来连接x吃的,x+2*n用来连接x被吃的。

1 x y时,如果 x吃y 或 x被y吃,那么为假话,

否则x与y同类,x吃的y也吃,x被吃的y也被吃;

2 x y时,如果 x与y同类(x与x自然也是同类) 或 y吃x,那么为假话,

否则x吃y,y被x吃,y吃x被吃的.

 

——代码

技术分享
 1 #include <cstdio> 2 #include <iostream> 3 #define N 1000001 4  5 int n, k, ans; 6 int f[N]; 7  8 inline int read() 9 {10     int x = 0, f = 1;11     char ch = getchar();12     for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1;13     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0;14     return x * f;15 }16 17 inline int find(int x)18 {19     return x == f[x] ? x : f[x] = find(f[x]);20 }21 22 inline void connect(int x, int y)23 {24     x = find(x);25     y = find(y);26     if(x ^ y) f[x] = y;27 }28 29 int main()30 {31     int i, j, x, y, z;32     n = read();33     k = read();34     for(i = 1; i <= 3 * n; i++) f[i] = i;35     for(i = 1; i <= k; i++)36     {37         z = read();38         x = read();39         y = read();40         if(x > n || y > n)41         {42             ans++;43             continue;44         }45         if(z == 1)46         {47             if(find(x + n) == find(y) || find(x + 2 * n) == find(y))48             {49                 ans++;50                 continue;51             }52             connect(x, y);53             connect(x + n, y + n);54             connect(x + 2 * n, y + 2 * n);55         }56         else57         {58             if(find(x) == find(y) || find(x + 2 * n) == find(y))59             {60                 ans++;61                 continue;62             }63             connect(x + n, y);64             connect(y + 2 * n, x);65             connect(y + n, x + 2 * n);66         }67     }68     printf("%d\n", ans);69     return 0;70 }
View Code

 

还有带权并查集的做法

正在努力学习。。

[luoguP2024] 食物链(并查集)