题目是poj1182
我和ac代码只有 merge 函数不一样,但是不知道哪里出问题了
求大佬帮忙
void merge(int a,int b,int r){
s[a]=find(a); s[b]=find(b);
if(s[a]==s[b]){
if(((d[a]-d[b]+3)%3)!=r-1) ans++;
}
else{
s[s[a]]=s[b];
d[s[a]]=(r-1-d[a]+d[b]+3)%3;
}
}
void merge(int x, int y, int relation){ //合并
int rootx = find(x); int rooty = find(y);
if (rootx == rooty){
if ((relation - 1) != ((d[x] - d[y] + 3) % 3)) //判断矛盾
ans++;
}
else {
s[rootx] = rooty; //合并
d[rootx] = (d[y] - d[x] + relation - 1+3) % 3; //更新权值
}
}
上面的是我的,下面是ac代码
最后面是完整ac代码
#include <iostream>
#include <stdio.h>
using namespace std;
const int N = 50005;
int s[N]; //集
int d[N]; // 0:同类; 1:吃; 2:被吃
int ans;
void init_set(){ //初始化
for(int i = 0; i <= N; i++) { s[i] = i; d[i] = 0; }
}
int find_set(int x){ //带权值的路径压缩
if(x != s[x]) {
int t = s[x]; //记录父结点
s[x] = find_set(s[x]); //路径压缩。递归最后返回的是根结点
d[x] = (d[x] + d[t]) % 3; //权值更新为x到根结点的权值
}
return s[x];
}
void merge_set(int x, int y, int relation){ //合并
int rootx = find_set(x); int rooty = find_set(y);
if (rootx == rooty){
if ((relation - 1) != ((d[x] - d[y] + 3) % 3)) //判断矛盾
ans++;
}
else {
s[rootx] = rooty; //合并
d[rootx] = (d[y] - d[x] + relation - 1) % 3; //更新权值
}
}
int main(){
int n, k; cin >> n >> k;
init_set();
ans = 0;
while (k--){
int relation, x, y; scanf("%d%d%d",&relation,&x,&y);
if( x>n || y>n || (relation==2 && x==y) ) ans++;
else merge_set(x,y,relation);
}
cout << ans;
return 0;
}