按照挑战程序设计的思路敲的,有个坑,要用scanf,之前试过cin优化,还是无法逃脱TLE的命运,换成scanf可以过
对于题目本身的解法,有点似懂非懂,当然,并查集的几个基本操作复习了一下,然后,不是很懂,为什么unite(x,x + n)
x + n里面不是空的么……
后来懂了,x + n里面是空的,但是unite的是下标代表的数,fine。
主要程序很简洁,这个……很漂亮的
#include <iostream>
#include <cstdio>
#define N 100005
using namespace std;
int par[150014];
int T[N],X[N],Y[N];
int find(int x){
int r = x;
while(r != par[r]){
r = par[r];
}
// int i = x,j;
// while(i != r){
// j = par[i];
// par[i] = r;
// i = j;
// }
return r;
}
void unite(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx != fy)
par[fx] = fy;
}
bool same(int x,int y){
return find(x) == find(y);
}
int main(){
std::ios::sync_with_stdio(false);
int n,k,cnt = 0;
int x,y,t;
// cin>>n>>k;
scanf("%d%d",&n,&k);
for(int i = 0; i < n * 3; i++)
par[i] = i;
for(int i = 0; i < k; i++){
// cin>>T[i]>>X[i]>>Y[i];
scanf("%d%d%d",&T[i],&X[i],&Y[i]);
t = T[i];
x = X[i] - 1; y = Y[i] - 1;//把范围变成 0 ~ N - 1
if(x < 0 || x >= n || y < 0 || y >= n){
cnt++;
continue;
}
if(t == 1){
if(same(x, y + n) || same(x, y + 2 * n)){
cnt++;
}else{
unite(x, y);
unite(x + n, y + n);
unite(x + 2 * n, y + 2 * n);
}
}else if(t == 2){
if(same(x, y) || same(x, y + 2 * n)){
cnt++;
}else{
unite(x, y + n);
unite(x + n, y + 2 * n);
unite(x + 2 * n, y);
}
}
}
// cout<<cnt<<endl;
printf("%d\n",cnt);
return 0;
}