并查集(POJ1182)

时间:2023-03-09 07:29:41
并查集(POJ1182)

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

定义一种关系R(x,y),x > y 时 R(x,y) = 2;x = y 时 R(x,y)= 1;x < y 时 R(x,y) = 0

则R(x,y)有如下运算法则:
R(x,y) = (R(x,u) - R(y,u) + 4) % 3

R(x,y) = (R(x,u) + R(u,y) + 2) % 3

...

用并查集维持这种关系

 /**************************************************************
作者:陈新
邮箱:cx2pirate@gmail.com
用途:poj1182
时间:2014年 4月12日 15:00
测试:12745220 Will4944 1182 Accepted 548K 282MS C++ 967B 2014-04-12 14:58:49
*************************************************************/ #include <stdio.h>
#define MAX_N 50005 int pre[MAX_N]; //并查集
int rel[MAX_N]; //与根节点关系 void init();
int find(int u);
void unite(int r,int u,int v); int main(){
int m,n;
// while(scanf("%d%d",&m,&n) != EOF){ 我去!。。。。
scanf("%d%d",&m,&n);
int r,u,v,sum = ;
init();
for(int i = ;i < n;i++){
scanf("%d%d%d",&r,&u,&v);
if(u > m || v > m || (r == && u == v)){
sum++;
continue;
}
if(find(u) == find(v)){
if((rel[u] - rel[v] + ) % != r){
sum++;
}
}
else{
unite(r,u,v);
}
} printf("%d\n",sum);
// }
} void init(){
for(int i = ;i < MAX_N;i++){
pre[i] = i;
rel[i] = ;
}
} int find(int u){
if(pre[u] == u){
return u;
}
int t = find(pre[u]);
rel[u] = (rel[u] + rel[pre[u]] + ) % ;
pre[u] = t;
return pre[u];
} void unite(int r,int u,int v){
int pu = find(u);
int pv = find(v);
pre[pu] = pv;
rel[pu] = (r + rel[v] - rel[u] + ) % ;
}