分析:
主要是第二個條件,題目的意思是,如果我再外面再包一圈(
判斷一個點在不在連通塊中:並查集就行了。
每一次加一個正方體,相當於圖的刪邊,這個比較困難,如果倒着刪除正方體,就相當於圖加邊,容易實現,這題也就變成了一個離線並查集。
代碼:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef vector <int> VI;
typedef pair <int,int> PII;
#define FOR(i,x,y) for(int i = x;i < y;++ i)
#define IFOR(i,x,y) for(int i = x;i > y;-- i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
const int maxX = 102;
const int maxN = 100010;
int n;
int dx[6] = {-1,1,0,0,0,0},dy[6] = {0,0,-1,1,0,0},dz[6] = {0,0,0,0,-1,1};
bool vis[maxX][maxX][maxX];
int mat[maxX][maxX][maxX];
int fa[maxX*maxX*maxX];
pair <PII,int> pos[maxN];
int findroot(int x) {return fa[x] == x ? x : fa[x] = findroot(fa[x]);}
void merge(int x,int y) {fa[findroot(x)] = findroot(y);}
bool issmblock(int x,int y) {return findroot(x) == findroot(y) ? true : false;}
bool judge(int x,int y,int z){
if(x >= maxX || x < 0 || y >= maxX || y < 0 || z >= maxX || z < 0)
return false;
return true;
}
bool legal(int x,int y,int z){
bool flag = false;
FOR(i,0,6){
int nx = x+dx[i],ny = y+dy[i],nz = z+dz[i];
if(!judge(nx,ny,nz)) continue;
if(mat[nx][ny][nz]) {flag = true;break;}
}
return flag;
}
void dfs(int x,int y,int z,int pa){
int val = x*maxX*maxX+y*maxX+z;
if(vis[x][y][z] || mat[x][y][z]) return;
vis[x][y][z] = true;
fa[val] = pa;
FOR(i,0,6){
int nx = x+dx[i],ny = y+dy[i],nz = z+dz[i];
if(!judge(nx,ny,nz)) continue;
if(!vis[nx][ny][nz]) dfs(nx,ny,nz,pa);
}
}
bool work(){
scanf("%d",&n);
memset(mat,0,sizeof(mat));
FOR(i,0,maxX) FOR(j,0,maxX) mat[i][j][0] = 1;
bool flag = true;
FOR(i,0,n){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
pos[i] = mp(mp(x,y),z);
if(flag && mat[x][y][z]) {flag = false;}
mat[x][y][z] = 1;
if(flag && !legal(x,y,z)) {flag = false;}
}
if(!flag) return false;
memset(vis,false,sizeof(vis));
FOR(i,0,maxX*maxX*maxX) fa[i] = i;
FOR(i,0,maxX) FOR(j,0,maxX) FOR(k,0,maxX) dfs(i,j,k,i*maxX*maxX+j*maxX+k);
int tar = maxX*maxX*maxX-1;
IFOR(i,n-1,-1){
int x = pos[i].fi.fi,y = pos[i].fi.se,z = pos[i].se;
int last = x*maxX*maxX+y*maxX+z;
FOR(j,0,6){
int nx = x+dx[j],ny = y+dy[j],nz = z+dz[j];
if(!judge(nx,ny,nz)) continue;
if(mat[nx][ny][nz]) continue;
int cur = nx*maxX*maxX+ny*maxX+nz;
merge(last,cur);
}
mat[x][y][z] = 0;
if(!issmblock(last,tar)) {flag = false;break;}
}
return flag;
}
int main(){
//freopen("test.in","r",stdin);
int T; scanf("%d",&T);
while(T--){
if(work()) printf("Yes\n");
else printf("No\n");
}
return 0;
}