简单环路

题目描述

有一个N x M 大小的地图,地图中的每个单元包含一个大写字母。
若两个相邻的(这里的相邻指“上下左右”相邻)点上的字母相同,我们可以用线段连接这两个点。
若存在一个包含同一字母的环路,那么连接这些点我们可以得到一个多边形,
当且仅当多边形的边数大于等于4时,我们称这幅地图中存在“简单环路”。
现在给你一份地图,你来判断是否存在“简单环路”。
列如:
3 4
AAAA
ABCA
AAAA
字符“A”可以构成一个“简单环路”,其边数为4。

输入

第一行输入两个正整数n,m,2<=n,m<=50,分别表示地图的行列数。
接下来输入n行,每行m个大写字母。

输出

若存在“简单环路”输出“Yes”,否则输出“No”。

样例输入

复制
3 4
AAAA
ABCA
AADA

样例输出

复制
No


大致分析:

  要想存在一个多边形,至少需要四条边,因为只能上下左右移动。

  方法1:重新构图——把每个字母当成一个点,判断上下左右如果有相同的则连上一条边。用tarjan算法来进行判环,若遇见连接到更小的搜索序号dfn[]时,则可以认为这时找到了一个环,然后把这个环弹出来,数数长度(看是否满足要求),再逆序放回去。

方法2:据说搜索就可以了,只有相同字符之间的才可以进行搜索;后台数据比较弱,我用错误的代码都过了。


答案:

  

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include<math.h>
#include <string.h>
#include<set>
using namespace std;
#define inf 0x3f3f3f3f
#define maxn 10000000
const double pi=acos(-1.0);
#define ll long long
#define N 55
#define M 50*50+5
char a[55][55];
vector<int>G[M];//表示每个点的周围四个点的情况
int low_link[M],dfn[M],inst[M];
int Time;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0} };
int n,m;
bool flag;
stack<int>st;
void judge(int i,int j,int num){for(int k=0;k<=3;k++){int dx=i+dir[k][0];int dy=j+dir[k][1];if(dx>=0&&dx<=n-1&&dy>=0&&dy<=m-1&&a[dx][dy]==a[i][j]){G[num].push_back(dx*m+dy);}}
}
void init(){Time=0;flag=false;for(int i=0;i<=n*m;i++)G[i].clear();memset(low_link,0,sizeof(low_link));memset(dfn,0,sizeof(dfn));memset(inst,0,sizeof(inst));while(!st.empty())st.pop();
}
void tarjan(int u,int fa){low_link[u]=dfn[u]=++Time;st.push(u);inst[u]=1;for(int i=0;i<(int)G[u].size();i++){int v=G[u][i];if(!dfn[v]){tarjan(v,u);low_link[u]=min(low_link[u],low_link[v]);}else if(inst[v]==1&&v!=fa){low_link[u]=min(low_link[u],dfn[v]);stack<int>q;int cnt=1;while(st.top()!=v){q.push(st.top());st.pop();cnt++;}if(cnt>=4){flag=true;// printf("u=%d v=%d\n",u,v);
            }while(q.size()>0){st.push(q.top());q.pop();}}}if(low_link[u]==dfn[u]){while(st.top()!=u){//  printf("u=%d %d\n",u,st.top());inst[st.top()]=0;st.pop();}inst[st.top()]=0;st.pop();}}
void debug(){for(int i=0;i<n;i++){for(int j=0;j<m;j++){int num=i*m+j;for(int v=0;v<G[num].size();v++){printf("%d:%d ",num,G[num][v]);}cout<<endl;}}
}
int main(){while(scanf("%d%d",&n,&m)!=EOF){init();for(int i=0;i<n;i++)scanf("%s",a[i]);for(int i=0;i<n;i++){for(int j=0;j<m;j++){int num=i*m+j;judge(i,j,num);}}//   debug();for(int i=0;!flag&&i<n;i++){for(int j=0;!flag&&j<m;j++){int num=i*m+j;if(!dfn[num]){tarjan(num,-1);//if(flag==true)//  printf("Yes num=%d\n",num);
                }}}if(flag==true)printf("Yes\n");elseprintf("No\n");}return 0;
}

View Code

  

转载于:https://www.cnblogs.com/zhazhaacmer/p/9034648.html

【搜索/tarjan找环】zznu-简单环路相关推荐

  1. P1444 [USACO1.3]虫洞 wormhole,新手向超详细讲解(搜索、判环、拆点、好题)

    题目传送门 题目不难,但是有很多细节和技巧. 分析题意 首先我们根据题意发现奶牛一共只会出现两种动作(两种情况),一是向右走,二是传送. 我们并不知道奶牛的位置,而题目所求的是有多少种分配虫洞传送的分 ...

  2. CodeForces - 1335F Robots on a Grid(拓扑找环+反向dfs/倍增)

    题目链接:点击查看 题目大意:给出一个 n * m 的矩阵,矩阵的每一个格子都有一个颜色,颜色非黑即白,除此之外每个格子还有一个指令,分别为: ' U ':向上一个单位 ' D ':向下一个单位 ' ...

  3. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

  4. 【2019.7.16 NOIP模拟赛 T1】洗牌(shuffle)(找环)

    找环 考虑每次洗牌其实是一次置换的过程,而这样必然就会有循环出现. 因此我们直接通过枚举找出每一个循环,询问时只要找到环上对应的位置就可以了. 貌似比我比赛时被卡成\(30\)分的倍增简单多了? 代码 ...

  5. 删除下拉框只找23火星软件_下拉框搜索就找23火星软件/下拉框软件速来火星下拉...

    现在不管做什么,都是需要流量,有了流量才能把自己手上的生意做好.不管是实体店微商,电商,还是互联网创业者,如果你拥有了流量,那么不管你选择去做什么产品,你都会一步到位,一飞冲天,实现自己的梦想.但是现 ...

  6. ug提示找不到html文件,[图文教程] 以下文件无法加载,导致打开操作失败: 使用当前搜索选项找不到文件,部件已卸载...

    UG打开装配文件时提示:以下文件无法加载,导致打开操作失败: 使用当前搜索选项找不到文件,部件已卸载. 如下图所示: 这个问题,看到很多UG初学者有时就会问到这个问题,很简单的一个问题,但是有时有必要 ...

  7. 快慢指针判断单向链表是否有环及找环入口

    前言 关于快慢指针找环入口的这个问题,之前巴特跟我聊到过,印象比较深,今晚看学长在做的面试题,里面就出现了这个小知识. 发现有些东西不经意间就会用到,于是便出现此文.以后要努力做到善于总结,乐于总结. ...

  8. P2444 [POI2000]病毒(ACAM上找环)

    LINK 给出一些010101串,问是否存在无限长的某个010101串 使得给定的任何一个010101串都不是它的子串 普通考虑好像不太好弄,我们建出ACAMACAMACAM看看 预处理ed[i]ed ...

  9. 魔兽世界不同服务器集合石显示的内容,魔兽世界集合石插件屏蔽关键字分享,这下找队伍就简单了...

    原标题:魔兽世界集合石插件屏蔽关键字分享,这下找队伍就简单了 在魔兽世界里,用集合石插件来寻找队伍和队友是非常方便的.不过如今的集合石上面的广告比较多,不屏蔽一些关键词的话,玩家们只能在广告的夹缝里寻 ...

  10. NOI2013快餐店【图上找环+线段树】

    NOI 2013 快餐店 NOI 线段树 题目传送点 说白了,就是给个N个点N条边的图,然后求一个点(不一定是给的那N个点),到所有给定的点的路程最大值最小 =≡Σ((( つ•̀ω•́)つ我是蒟蒻,想 ...

最新文章

  1. Javascript将构造函数扩展为简单工厂
  2. postgresql 基础sql
  3. ORA-01180: can not create datafile 1 :解决一例
  4. 帐户分类 密码强度
  5. cgcs2000高斯平面直角坐标_8年级开学第一课:数系扩充到实数,几何模型搬到直角坐标系...
  6. vue2.0 自定义 生成二维码(QRCode)组件
  7. 监控mysql主从的工具_zabbix利用percona-toolkit工具监控Mysql主从同步状态
  8. 通过os中的os.path.basename获取路径中的文件名
  9. linux 生成excel格式的文件怎么打开乱码,导出的文件乱码怎么办(各位,汉字在excel表格中显示乱码,怎么办)...
  10. 有哪些有关java类最新发表的毕业论文呢?
  11. 上周内外盘行情回顾及交易情况2022.4.4
  12. 【六祎 - HTML模板】提交按钮模板-带特效
  13. 硬盘挂载 mount 详细步骤及遇到问题“Mount is denied because the NTFS volume is already exclusively opened”
  14. javaweb企业员工考勤管理系统案例
  15. 计算机网络安全基础东南大学,设计(东南大学计算机网络与安全).doc
  16. 地下水情监测仪应用库区安全行业
  17. 中小企业营销兵法_小型企业创建营销计划的技巧
  18. html图片叠,很棒的CSS3图片堆叠效果
  19. 人生经典定律[收藏] 1
  20. UE4 使用顶点绘制

热门文章

  1. 浅谈CURD系统和CRQS系统
  2. Ubuntu 20 / 21 - KDE 配置Nvidia 独立显卡
  3. 【Excel】Excel读取数据时,提示“服务器连接异常”
  4. pyftpdlib 创建ftpserver
  5. 微信公众平台开发——微信授权登录(OAuth2.0)
  6. 老闪创业那些事儿(9)——雏鹰计划(上)
  7. Linux 命令之 locale -- 设置和显示程序运行的语言环境
  8. 瑞士央行2022年巨亏1320亿瑞士法郎
  9. C18-PEG-ICG18碳烷基链-聚乙二醇-吲哚菁绿,Cholesterol-PEG-ICG胆固醇-聚乙二醇-吲哚菁绿
  10. 函数连续、可导、可微、连续可微