版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugarbliss/article/details/89488732
题目链接:http://poj.org/problem?id=1182
思路:带权并查集,主要是关系的定义,题目中给了A吃B, B吃C,C吃A,所以我们根据这个来定义关系:
- 0 : X被Y吃
- 1 : X和Y同类
- 2 : X吃Y
也可以定义0:同类 1:吃 2:被吃,只不过权值的关系不一样,中心还是要围绕A吃B, B吃C,C吃A这个定义。无论哪种定义,权值初始化一定要符合你定义的关系,第一种权值数组要初始化为1,第二种要初始化为0,,表示同类。
#include <stdio.h>
#include <string.h>
using namespace std;
const int N = 1e5+7;
int f[N], w[N], ans, n, k;
void init()
{
for(int i = 0; i <= n; i++)
f[i] = i, w[i] = 1;
}
int findd(int x)
{
if(f[x] == x) return x;
int t = f[x];
f[x] = findd(f[x]);
w[x] = (w[x] + w[t] + 2 + 3) % 3;
return f[x];
}
void unint(int d, int x, int y)
{
int tx = findd(x), ty = findd(y);
if(tx != ty)
{
f[tx] = ty;
w[tx] = (-w[x] + w[y] + d + 3) % 3;
}
else
{
if(((w[x] - w[y] + 1 + 3) % 3 ) != d) ans++;
}
}
int main()
{
scanf("%d%d",&n, &k);
int d, x, y; init();
while(k--)
{
scanf("%d%d%d",&d, &x, &y);
if(x > n || y > n || (d == 2 && x == y)) ans++;
else unint(d, x, y);
}
printf("%d\n",ans);
}
/*
100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5
*/