POJ 1182 食物链

来源:互联网 发布:linux 删除匹配文件名 编辑:程序博客网 时间:2024/06/06 00:10

http://poj.org/problem?id=1182

对于每只动物 i 创建3个元素,i-A, i-B, i-C,并用3 x N 个元素建立并查集,这个并查集维护如下信息:

# i - x 表示 i 属于种类i;

# 并查集里的每一组表示组内所有元素代表的情况都同时发生或不发生。

第一种  x 和 y属于同种类, 合并 x-A和y-A, x-B和y-B, x-C和y-C;

第二种 x 吃 y                          合并x-A和y-B,x-B和y-C, x-C和y-A;  

代码

#include <stdio.h>#include <stdlib.h>#include <string>#include <string.h>#include <map>using namespace std;#define MAX_N 50001*3#define MAX_K 100005int par[MAX_N], t[MAX_K], a[MAX_K], b[MAX_K], n, k;void init(){for (int i = 0; i <= n * 3; i++){par[i] = i;}}int find(int x){int y = x;while (y != par[y]){y = par[y];}while (x != par[x]){int px = par[x];par[x] = y;x = px;}return y;}void Union(int x, int y){int ra = find(x), rb = find(y);par[ra] = rb;}void slove(){int sum = 0, z, x, y;for (int i = 0; i < k; i++){z = t[i];x = a[i];y = b[i];if (x < 1 || x > n || y < 1 || y > n){sum++;continue;}if (z == 1){//x, y属于同一类if (find(x) == find(y + n) || find(x) == find(y + 2 * n)){sum++;continue;}else{Union(x, y);Union(x + n, y + n);Union(x + 2 * n, y + 2 * n);}}else{//想吃yif (find(x) == find(y) || find(x) == find(y + 2 * n)){sum++;continue;}else{Union(x, y + n);Union(x + n, y + 2 * n);Union(x + 2 * n, y);}}}printf("%d\n", sum);return;}int main(){//freopen("1.in","r",stdin);int i;scanf("%d %d",&n,&k);init();for (i = 0; i < k; i++){scanf("%d %d %d", &t[i], &a[i], &b[i]);}slove();system("pause");return 0;}


0 0
原创粉丝点击