并查集的合并函数求解
  • 板块学术版
  • 楼主dingxingjian
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/11/20 21:46
  • 上次更新2024/11/21 06:59:55
查看原帖
并查集的合并函数求解
1463361
dingxingjian楼主2024/11/20 21:46

题目是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;
}

2024/11/20 21:46
加载中...