题目大意是有一个DIMA四种字母组成的矩阵,要在矩阵中找最长的DIMADIMADIMA……串,连接方式为四方向连接,问最长能找到多少DIMA。字母可以重复访问,如果DIMA串成环,即可以取出无限长的DIMA串,则输出特定字符串,若没有DIMA串,也输出另一特定字符串,否则输出最长多少DIMA串。

这是我大一暑假的时候做的,并且当时WA在第23组上,后来就没继续做这个题了,现在不想看大一的代码了。

重新想了一下,其实就是判图中是否有环,无环的话,DIMA的链最长多少,也就是找图中以D字母开头的最长链。

那么读入之后对D->I  I->M  M->A  A->D 进行建边,并判环以及求最长链即可。

我考虑判环和求最长链长度都可以通过DFS实现,所以就只写了一个DFS函数。

DFS当然是没有写错的,但是发现在第10组T了。想了一下,DFS总复杂度是O(n^2+m)的,m为边数,因为所有点和边都只会被DFS一次,我全部从D字母开始搜索。此时因为我判环有提前return的操作,会导致vis没有清空,因此我在每次DFS前有memset掉vis数组的操作。如果D特别多,则memset每次都是O(n^2)的复杂度,就会超时。我修改了一下,将DFS过程中的return前都将vis置为0,就不用memset了,于是就过了。

其实如果将判环和求最长链分开,或许就不会出现这样的问题,比如用拓扑序判环,肯定不会出现大量memset。判完环再求最长链,则已经知道图中没有环,DFS每个点必定只需要访问一次,就不需要memset了。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define PB push_back
  4. #define MP make_pair
  5. typedef long long ll;
  6. const int mod = 1e9 + ;
  7. const int INF = 0x3f3f3f3f;
  8. const double eps = 1e-;
  9. const int maxn = 1e6 + ;
  10.  
  11. int n,m;
  12. int xx[] = {,-,,};
  13. int yy[] = {,,,-};
  14. char s[][];
  15. int id[][];
  16. int dis[maxn];
  17. int head[maxn],point[maxn<<],nxt[maxn<<],size;
  18. int vis[maxn];
  19. bool flag = false;
  20.  
  21. void init(){
  22. size = ;
  23. memset(head,-,sizeof(head));
  24. memset(dis,,sizeof(dis));
  25. memset(vis,,sizeof(vis));
  26. flag = false;
  27. }
  28.  
  29. void add(int a, int b){
  30. point[size] = b;
  31. nxt[size] = head[a];
  32. head[a] = size++;
  33. }
  34.  
  35. void dfs(int s){
  36. if(dis[s])return;
  37. vis[s] = ;
  38. dis[s] = ;
  39. for(int i = head[s] ; ~ i ; i = nxt[i]){
  40. int j = point[i];
  41. if(vis[j]){flag = true;vis[s] = ;return;}
  42. dfs(j);
  43. if(flag){vis[s] = ;return;}
  44. dis[s] = max(dis[s],dis[j]+);
  45. }
  46. vis[s] = ;
  47. }
  48.  
  49. int main(){
  50. scanf("%d%d",&n,&m);
  51. for(int i = ; i <= n ; ++ i)scanf("%s",s[i]+);
  52. int cnt = ;
  53. for(int i = ; i <= n ; ++ i){
  54. for(int j = ; j <= m ; ++ j){
  55. id[i][j] = ++ cnt;
  56. }
  57. }
  58. init();
  59. for(int i = ; i <= n ; ++ i){
  60. for(int j = ; j <= m ; ++ j){
  61. for(int k = ; k < ; ++ k){
  62. int dx = i + xx[k];
  63. int dy = j + yy[k];
  64. if(dx < || dx > n || dy < || dy > m)continue;
  65. if(s[i][j] == 'D' && s[dx][dy] == 'I')add(id[i][j],id[dx][dy]);
  66. if(s[i][j] == 'I' && s[dx][dy] == 'M')add(id[i][j],id[dx][dy]);
  67. if(s[i][j] == 'M' && s[dx][dy] == 'A')add(id[i][j],id[dx][dy]);
  68. if(s[i][j] == 'A' && s[dx][dy] == 'D')add(id[i][j],id[dx][dy]);
  69. }
  70. }
  71. }
  72. int ans = ;
  73. for(int i = ; i <= n ; ++ i){
  74. for(int j = ; j <= m ; ++ j){
  75. if(s[i][j] != 'D')continue;
  76. dfs(id[i][j]);
  77. if(flag == true){
  78. printf("Poor Inna!\n");
  79. return ;
  80. }
  81. if(dis[id[i][j]] > ans)ans = dis[id[i][j]];
  82. }
  83. }
  84. ans /= ;
  85. if(ans)printf("%d\n",ans);
  86. else printf("Poor Dima!\n");
  87. return ;
  88. }

cf374C Inna and Dima dfs判环+求最长链的更多相关文章

  1. HDU 4612 Warm up tarjan缩环+求最长链

    Warm up Problem Description   N planets are connected by M bidirectional channels that allow instant ...

  2. cf1278D——树的性质+并查集+线段树/DFS判环

    昨天晚上本来想认真打一场的,,结果陪女朋友去了.. 回来之后看了看D,感觉有点思路,结果一直到现在才做出来 首先对所有线段按左端点排序,然后用并查集判所有边是否联通,即遍历每条边i,和前一条不覆盖它的 ...

  3. Atcoder Grand Contest 032C(欧拉回路,DFS判环)

    #include<bits/stdc++.h>using namespace std;int vis[100007];vector<int>v[100007];vector&l ...

  4. LG2272/BZOJ1093 「ZJOI2007」最大半连通子图 Tarjan缩点+DAG求最长链

    问题描述 LG2272 BZOJ1093 题解 观察半联通的定义,发现图中的一些结点,构成的链一定是一个半联通子图. 此时存在的环可能会干扰求解,于是\(\mathrm{Tarjan}\)缩点. 于是 ...

  5. Codeforces 374 C Inna and Dima (DFS)

    Inna and Dima 题意:从图上的任意一个D点按着DIMADIMA的顺序走,问一共可以经过多少个DIMA,如果经过0个DIMA就输出“Pool DIma!“,如果可以有无数多个DIMA就输出” ...

  6. 【题解】CF374C Inna and Dima

    题面传送门 解决思路 本题是找最长路的图上问题,所以先考虑如何建图. 首先把每一个字母转化为数字,然后对于每一个点枚举四个方向,如果有下一个字母,就向那个点建一条边,可以用 \(vector\) 存图 ...

  7. UVA818-Cutting Chains(二进制枚举+dfs判环)

    Problem UVA818-Cutting Chains Accept:393  Submit:2087 Time Limit: 3000 mSec  Problem Description Wha ...

  8. 洛谷2444(Trie图上dfs判环)

    要点 并没问具体方案,说明很可能不是构造. 思考不断读入这个文本串,然后中间不出现某些文法的串.啊,这就是个自动机. 将不合法串使用ac自动机构成一个Trie图,我们需要的字符串就是在这个自动机上无限 ...

  9. CodeForces-1217D (拓扑排序/dfs 判环)

    题意 https://vjudge.net/problem/CodeForces-1217D 请给一个有向图着色,使得没有一个环只有一个颜色,您需要最小化使用颜色的数量. 思路 因为是有向图,每个环两 ...

随机推荐

  1. 使用Python统计函数绘制复杂图形matplotlib

    一.堆积图 1.堆积柱状图 如果将函数bar()中的参数bottom的取值设定为列表y.列表y1代表另一个数,函数bar(x,y1,bottom=y,color="r")就会输出堆 ...

  2. Java作业:第一次过程性考核 ——长春职业技术学院 16级网络工程

    Java作业:第一次过程性考核 ••<结构化程序设计>•• 考核目标:初步了解Java基本语法规则,学习结构化程序设计思想. 码云链接:https://gitee.com/SoridoD/ ...

  3. JavaScript “函数重载”

    函数重载(function overloading)必须依赖两件事情:判断传入参数数量的能力和判断传入参数类型的能力. JavaScript的每个函数都带有一个仅在这个函数范围内作用的变量argume ...

  4. JAVAEE 第六周

    JSF 生命周期: FacesServlet 充当用户和 JSF 应用程序之间的纽带.它在明确限定的 JSF 生命周期(规定了用户请求之间的整个事件流)的范围内工作. 1.   当JSF页面上的一个事 ...

  5. jmeter如何进行MQTT性能测试(测试前期准备一,性能测试需求)

    接到一个有关MQTT的性能测试任务,把查找资料到解决问题的过程都记录.分享下 首先先科普下性能测试中相关术语的解释及 说到性能测试.负载测试.压力测试.并发测试,很多人都是混合使用,或者一会叫压力测试 ...

  6. 2D 加速图形界面开发源代码亲写 想买来学习得加qq 313244484 20万当前代码,完整400万包写完

    #include "StdAfx.h" #include "GUIFrame.h" #include <stdlib.h> #include < ...

  7. JSON与JS对象的区别

    <script> var obj2={};//这只是JS对象 var obj3={width:100,height:200};/*这跟JSON就更不沾边了,只是JS的 对象 */ var ...

  8. java基础知识—运算符和基本选择结构

    1.保存真假,使用boolean变量 boolean有两个值:true 真 false 假 2.从控制台接受输入信息,通过创建扫描器 Sacnner input=new Sacnner(System. ...

  9. vue项目中,使用vue-awesome-swiper插件实现轮播图

    一.安装 npm install vue-awesome-swiper 二.项目中引入 import 'swiper/dist/css/swiper.css'import {swiper,swiper ...

  10. linux中sed命令批量修改

    sed命令下批量替换文件内容  格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 -rl 路径` 文件名 -i 表示inplace edit,就地修改文件 ...