51nod1416-搜索&剪枝|并查集-两点

58 篇文章 0 订阅
3 篇文章 0 订阅

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1416
中文题意。
开始t了一发。后来发现了剪枝。
那就是如果再dfs的过程中发现了以前搜索的点,并且这个点不是当前搜索点的父亲节点,那么必然已经成环,并且大小至少为4
并查集没怎么看懂。补

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
/*
*/
const int maxn=51;
int m,n;
int fx[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool vis[maxn][maxn];
char k[maxn][maxn];
bool flag;
char col;
int unix;
int uniy;
void dfs(int i,int j,int sum,int fax,int fay){
     if(flag) return ;
     if(sum>=4&&i==unix&&j==uniy){
        flag=true;return;
     }
     for(int ii=0;ii<4;ii++){
         int x=i+fx[ii][0];
         int y=j+fx[ii][1];
         if(x<1||x>m||y<1||y>n) continue;
         if(vis[x][y]&&k[x][y]==col&&sum>=4){
            if(x!=fax&&y!=fay){
            flag=true;break;
            }
         }
         if(!vis[x][y]&&k[x][y]==col){
             vis[x][y]=true;
             dfs(x,y,sum+1,i,j);
             //vis[x][y]=false;
         }
     }
}
int main()
{   while(~scanf("%d%d",&m,&n)){
          for(int i=1;i<=m;i++){
              for(int j=1;j<=n;j++){
                  scanf(" %c",&k[i][j]);
              }
          }
          flag=false;
          for(int i=1;i<=m&&!flag;i++){
              for(int j=1;j<=n&&!flag;j++){
                  memset(vis,false,sizeof(vis));
                  col=k[i][j];
                  unix=i;
                  uniy=j;
                  dfs(i,j,1,-1,-1);
              }
          }
          if(flag)
            puts("YES");
          else
            puts("NO");
     }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值