题目链接:食物链
中文题目,题意很好理解。类似于poj2492 A Bug's Life
在这里动物只有3种A,B,C,如果A吃B,我们可以将A对B的偏移量定为1。这题关键在于用一个数组记录每个点相对于根节点的偏移量,在合并两个集合的时候,注意保持当前两个节点的偏移量差为1, 在路径压缩过程中,依然采用递归形式,将路径上的偏移量层层改变,如果A和B偏移量之差为1, A吃B;如果为0, 表示为同类。关键在于找到修改偏移量的公式。做了2429,我感觉这题也很水!
代码
#include<stdio.h>
#include<stdlib.h>
#define NN 50004
int ans;
int bin[NN], rank[NN];
int offset[NN];
int Find(int x){
if (x != bin[x]){
int t = Find(bin[x]);
offset[x] = (offset[bin[x]] + offset[x]) % 3;
return bin[x] = t;
}
return x;
}
void Merge(int d, int x, int y){
int fx, fy;
fx = Find(x);
fy = Find(y);
if (fx == fy){
if (d == 1){
if (offset[x] != offset[y]){
ans++;
}
}else{
if ((offset[x] - offset[y] + 3) % 3 != 1){
ans++;
}
}
}else{
if (d == 1){
bin[fx] = fy;
offset[fx] = (offset[y] - offset[x] + 3) % 3;
}else{
bin[fx] = fy;
offset[fx] = (offset[y] + 4 - offset[x]) % 3;
}
}
}
int main()
{
int K, X, Y, D, i, N;
// freopen("data.in", "r", stdin);
// freopen("data.out", "w", stdout);
scanf("%d%d", &N, &K);
for (i = 1; i <= N; i++){
bin[i] = i;
rank[i] = 0;
offset[i] = 0;
}
while (K--){
scanf("%d%d%d", &D, &X, &Y);
if ((D == 2 && X == Y) || X > N || Y > N){
ans++;
continue;
}
Merge(D, X, Y);
}
printf("%d\n", ans);
// system("pause");
return 0;
}
这题我怕麻烦就没有按秩合并,不过也过了! 呵呵