hihocoder 1291 : Building in Sandbox (離線並查集)

分析:

主要是第二個條件,題目的意思是,如果我再外面再包一圈(x=0,y=0,x=101,y=101,z=101 )這5 個面上的點能夠不經過正方體到達指定位置x ,我們設這5 個面的所在的連通圖是p 。換種問法就是,指定位置x 是不是在連通圖p 中。

判斷一個點在不在連通塊中:並查集就行了。

每一次加一個正方體,相當於圖的刪邊,這個比較困難,如果倒着刪除正方體,就相當於圖加邊,容易實現,這題也就變成了一個離線並查集。

ps :感覺這題很不錯

代碼:

#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;
}

發佈了157 篇原創文章 · 獲贊 13 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章