(带权并查集)如果你也WA30pts,只过了1,3,9
查看原帖
(带权并查集)如果你也WA30pts,只过了1,3,9
800703
xxxxxxxb楼主2023/8/21 22:56
#include <bits/stdc++.h>
using namespace std;
const int N = (int)5e4+7;
int n,k;
int opt,x,y,ans;

struct dsu {
	int pa[N],d[N];
	void init() {
		for(int i = 1;i <= n;++i) pa[i]=i,d[i]=0;
	}
	int find(int x) {
		if(x==pa[x])return x;
		int f = pa[x];
		pa[x] = find(pa[x]);
		d[x] = (d[x] + d[f] + 3) % 3;
		return pa[x];
	}
	void uni(int x,int y,int v) {
		int fx = find(x),fy = find(y);
		if(fx==fy) return;
		pa[fx] = fy;
		d[fx] = (v + d[y] - d[x] + 3) % 3;
	}
} d;

int main() {
	scanf("%d%d",&n,&k);
	d.init();
	while(k--) {
		scanf("%d%d%d",&opt,&x,&y);
		if(x>n||y>n) {
			++ans;
			continue;
		}
		if(opt==1) {
			int fx = d.find(x),fy = d.find(y);
			if(fx==fy) {
				if(d.d[x] != d.d[y]) {
					++ans;
					continue;
				}
			} else {
				d.uni(x,y,0);
			}
		} else {
			if(x==y) {
				++ans;
				continue;
			}
			int fx = d.find(x),fy=d.find(y);
			if(fx==fy) {
				if((d.d[x]-d.d[y]+3)%3!=1) { // !!!这里写成 d.d[x] != d.d[y] 会错 :: x可能被y捕食(d[x]-d[y]==2)
					++ans;
					continue;
				}
			} else {
				d.uni(x,y,1);
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}
2023/8/21 22:56
加载中...