代码1.
#include <stdio.h>
#define N 50000
struct item
{
int p;
int rank;
};
struct item items[3*N + 3];
int count;
int ret;
void init(void)
{
int i;
for(i = 1; i <= 3*count; i++)
{
items[i].p = i;
items[i].rank = 0;
}
}
int find_set(int x)
{
if(items[x].p != x)
{
items[x].p = find_set(items[x].p);
}
return items[x].p;
}
void combine(int x, int y)
{
if(items[x].rank > items[y].rank)
{
items[y].p = x;
}
else
{
items[x].p = y;
if(items[x].rank == items[y].rank)
{
items[y].rank++;
}
}
}
void solve(int x, int y, int action)
{
if( x > count || y > count)
{
ret++;
return;
}
if( action == 2 && x == y)
{
ret++;
return;
}
if(action == 1)
{
if(find_set(x) == find_set(y+count) || find_set(x) == find_set(y + 2 * count))
{
printf("%d %d %d\n", action, x, y);
ret++;
return;
}
combine(find_set(x), find_set(y));
combine(find_set(x+count), find_set(y+count));
combine(find_set(x+ 2 * count), find_set(y+2 * count));
}
else if(action == 2)
{
if(find_set(x) == find_set(y) || find_set(x) == find_set(y+2*count))
{
printf("%d %d %d\n", action, x, y);
ret++;
return;
}
combine(find_set(x), find_set(y + count));
combine(find_set(x + count), find_set(y+2*count));
combine(find_set(x + 2 *count), find_set(y));
}
}
int main(void)
{
freopen("foodchain.txt", "r", stdin);
int K;
scanf("%d %d", &count, &K);
init();
int i;
for(i = 0; i < K; i++)
{
int action, x, y;
scanf("%d %d %d", &action, &x, &y);
solve(x, y, action);
}
printf("%d\n", ret);
return 0;
}
代码2:利用类似连通图的概念。
修改函数combine:
void combine(int x, int y)
{
if( x != y)
{
items[x].p = y;
}
}
参考: