蒟蒻求助,跟题解基本一样,为什么只有20分
查看原帖
蒟蒻求助,跟题解基本一样,为什么只有20分
1533449
Doctor_10086楼主2025/1/18 01:28
#include<iostream>
using namespace std;
const int max_n = 1e5 + 5;
int pre[max_n], re[max_n], num_ct, say_ct, ans = 0;//re代表relate关系数组,存储该节点与其父节点(路径压缩前)或其根节点(路径压缩后)的关系
int root(int x)                                            //最开始每个节点的根节点为自己,即同类,与根节点关系为0
{
	int temp = pre[x];
	if (x ^ pre[x]) {//路径压缩,将根节点变成父节点
		pre[x] = root(pre[x]);
		re[x] = (re[x] + re[temp]) % 3;//利用向量更新该节点与根节点关系,因为路径压缩要求节点与父节点关系变成与根节点关系
	}
	return pre[x];
}

int main()
{
	cin >> num_ct >> say_ct;
	for (int i = 0; i < num_ct; i++)pre[i] = i, re[i] = 0;//初始化根节点为其本身
	for (int i = 0; i < say_ct; i++) {
		int rela, x, y;
		cin >> rela >> x >> y;
		if (x > num_ct || y > num_ct || (rela == 2 && x == y)) {//x或y大于总数,是假话
			ans++;
			continue;
		}
		int a = root(x), b = root(y);
		if (rela == 1) {
			if (a == b && re[x] ^ re[y]) {//当x与y处于同一集合时,说明该话受之前的话影响,若x与其根节点关系和y与其根节点关系不同,即二者不是同类
				ans++;
				continue;
			}
			else if (a ^ b) {//x,y不在同一集合,二者没有联系,该话为真,联系二者
				pre[a] = b;
				re[a] = (re[y] - re[x] + 3) % 3;//更新做依附的根节点与其父节点的关系,其他节点不动,因为实质上不发生相连,只有根节点相连
			}                                      //为什么+0,因为实际上要加上我们x指向y向量的值做到向量连续,0同类,1捕食,2被捕食
		}
		if (rela == 2) {
			if (a == b && ((re[x] - re[y] + 3) % 3) ^ 1) {//当x,y同集合,根节点关系不为捕食,即1时,为假话
				ans++;
				continue;
			}
			if (a ^ b) {//x,y不在同一集合,二者没有联系,该话为真,联系二者
				pre[a] = b;
				re[a] = (re[x] - re[y] + 1 + 3) % 3;
			}
		}
	}//总的来说,merge主要是标记二者的关系在之前是否被真实诉说过
	cout << ans << endl;
	return 0;//其实可以改用结构体?
}
2025/1/18 01:28
加载中...