Graph Theme - BFS + Reverse Thinking K - Large Dumpling and 1/N Line Segment Tree

Title: http://qscoj.cn/#/contest/show/212
Thought: At first glance, adding trees online can't be done, but this problem can be done offline in reverse, deleting trees one by one, then deleting trees will have three situations:
(1) The deleted trees are surrounded by empty space: merge this area directly into the empty space.
(2) There is no space around the deleted tree: merge directly into the set of required blocks
(3) There are both open spaces and blocks around: then the blocks connected by this block will become empty spaces. BFS searches the connected block once and turns it into empty space (each block only changes into empty space once, so the maximum amount of searching is the size of the graph).

Note: The input coordinates are negative, so add 1000, which becomes the number in the range of 1-1999. Then the surrounding unnecessary is initialized to empty space.

Write wa for the first time all the time, think for a long time, feel right, rewrite it once.... I don't know what the problem is. I'll write a standard title in the future.
Code:

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5+66;
const int AX = 2e3+6;
struct Node{
    int x , y;
}a[MAXN];
int cnt , res;
int ans[MAXN];
int mp[AX][AX];
int dir[4][2] = {
    {1,0},
    {0,1},
    {-1,0},
    {0,-1}
};
int vis[AX][AX];
void bfs1(){
    memset( vis , 0 ,sizeof(vis) );
    queue<Node>que;
    Node tmp ;
    tmp.x = 0 ;tmp.y = 0;
    que.push(tmp);
    vis[0][0] = 1;
    while( !que.empty() ){
        Node pos = que.front();
        que.pop();
        for( int i = 0 ; i < 4 ; i++ ){
            Node q;
            q.x = pos.x + dir[i][0];
            q.y = pos.y + dir[i][1];
            if( q.x < 0 || q.x > 2000 || q.y < 0 || q.y > 2000 || vis[q.x][q.y] ) continue;
            if( mp[q.x][q.y] == 1 ) continue;
            que.push(q);
            vis[q.x][q.y] = 1;
            mp[q.x][q.y] = 2;
        }
    }
}

int check( int x , int y ){
    if( mp[x-1][y] == 2 && mp[x+1][y] == 2 && mp[x][y-1] == 2 && mp[x][y+1] == 2 ) return 1;
    if( mp[x-1][y] != 2 && mp[x+1][y] != 2 && mp[x][y-1] != 2 && mp[x][y+1] != 2 ) return 2;
    return 3;
}

void bfs( int x , int y ){
    queue<Node>que;
    Node tmp ;
    tmp.x = x ;
    tmp.y = y;
    que.push(tmp);
    while( !que.empty() ){
        Node pos = que.front();
        que.pop();
        for( int i = 0 ; i < 4 ; i++ ){
            Node q ;
            q.x = pos.x + dir[i][0];
            q.y = pos.y + dir[i][1];
            if( q.x < 0 || q.x > 2000 || q.y < 0 || q.y > 2000 ) continue;
            if( mp[q.x][q.y] != 0 ) continue;
            mp[q.x][q.y] = 2;
            res --;
            que.push(q);
        }
    }
}

int main(){
    int n ;
    scanf("%d",&n);
    memset( mp , 0 , sizeof(mp) );
    int x, y;
    for( int i = 0 ; i < n ; i++ ){
        scanf("%d%d",&x,&y);
        x += 1000;
        y += 1000;
        a[i].x = x;
        a[i].y = y;
        mp[x][y] = 1;
    }
    for( int i = 0 ; i <= 2000 ; i++ ){
        mp[i][0] = 2;
        mp[0][i] = 2;
        mp[2000][i] = 2;
        mp[i][2000] = 2;
    }
    bfs1();
    res = 0;
    cnt = 0;
    for( int i = 0 ; i <= 2000 ; i++ ){
        for( int j = 0 ; j <= 2000 ; j++ ){
            if( !mp[i][j] ){
                res ++;
            }
        }
    }
    ans[cnt++] = res;

    for( int i = n - 1; i > 0 ; i-- ){
        int f = check(a[i].x,a[i].y);
        if( f == 1 ){
            mp[a[i].x][a[i].y] = 2;
        }else if( f == 2 ){
            mp[a[i].x][a[i].y] = 0;
            res ++;
        }else{
            mp[a[i].x][a[i].y] = 2;
            bfs(a[i].x,a[i].y);
        }
        ans[cnt++] = res;
    }
    for( int i = cnt - 1 ; i >= 0 ; i-- ){
        printf("%d\n",ans[i]);
    }
    return 0 ;
}

Posted by Irksome on Tue, 05 Feb 2019 00:21:16 -0800