BestCoder Round #77 (div2) C

【题意】bc中文题,题意自己看啦!!!

【解题思路】 这是一个连通性的问题。你会发现如果将所有操作逆序来看的话就很容易用并查集来处理了。首先把所有的山峰都加到图中,然后逆序处理每个操作:对某次操作,在图中删除该位置的山峰,然后判断两个点是否联通,一旦联通就得到了结果。这里需要对China和India分别新建一个对应的节点。

【AC代码】

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 510;
char s[maxn][maxn];
int fa[maxn*maxn];
int x[maxn*maxn],y[maxn*maxn];
int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
int S,T,n,m,q;
int Code(int x,int y)
{
    return x*m+y;
}
int Find(int x)
{
    if(fa[x]==x)return fa[x];
    else
        return fa[x]=Find(fa[x]);
}
void union_set(int x,int y)
{
    int fx=Find(x),fy=Find(y);
    if(fx!=fy)
    {
        fa[fx]=fy;
    }
}
bool check(int x,int y)
{
    if(x>=0&&x<n&&y>=0&&y<m)return true;
    return false;
}

void Init()
{

}

int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0; i<n; i++)scanf("%s",s[i]);
        for(int i=0; i<=n*m+1; i++)fa[i]=i;
        S = n*m,T=n*m+1;
        scanf("%d",&q);
        for(int i=1; i<=q; i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            s[x[i]][y[i]]='1';
        }
        Init();
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(s[i][j]=='0')
                {
                    for(int k=0; k<4; k++)
                    {
                        int dx = i+dir[k][0];
                        int dy = j+dir[k][1];
                        if(!check(dx,dy)||s[dx][dy]=='1')continue;

                        union_set(Code(dx,dy),Code(i,j));
                    }
                    if(i==0)     union_set(S,Code(i,j));
                    if(i==n-1)   union_set(T,Code(i,j));
                }
            }
        }
        if(Find(S)==Find(T))
        {
            puts("-1");
            continue;
        }
        for(int i=q; i>=1; i--)
        {
            s[x[i]][y[i]]='0';
            for(int k=0; k<4; k++)
            {
                int dx = x[i]+dir[k][0];
                int dy = y[i]+dir[k][1];
                if(!check(dx,dy)||s[dx][dy]=='1')continue;
                union_set(Code(x[i],y[i]),Code(dx,dy));
            }
            if(x[i]==0)    union_set(S,Code(x[i],y[i]));
            if(x[i]==n-1)  union_set(T,Code(x[i],y[i]));
            if(Find(S)==Find(T))
            {
                printf("%d\n",i);
                break;
            }
        }
        if(Find(S)!=Find(T))
        {
            puts("0");
            continue;
        }
    }
    return 0;
}


你可能感兴趣的:(BestCoder Round #77 (div2) C)