cf374C Inna and Dima dfs判环+求最长链
题目大意是有一个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了。
- #include <bits/stdc++.h>
- using namespace std;
- #define PB push_back
- #define MP make_pair
- typedef long long ll;
- const int mod = 1e9 + ;
- const int INF = 0x3f3f3f3f;
- const double eps = 1e-;
- const int maxn = 1e6 + ;
- int n,m;
- int xx[] = {,-,,};
- int yy[] = {,,,-};
- char s[][];
- int id[][];
- int dis[maxn];
- int head[maxn],point[maxn<<],nxt[maxn<<],size;
- int vis[maxn];
- bool flag = false;
- void init(){
- size = ;
- memset(head,-,sizeof(head));
- memset(dis,,sizeof(dis));
- memset(vis,,sizeof(vis));
- flag = false;
- }
- void add(int a, int b){
- point[size] = b;
- nxt[size] = head[a];
- head[a] = size++;
- }
- void dfs(int s){
- if(dis[s])return;
- vis[s] = ;
- dis[s] = ;
- for(int i = head[s] ; ~ i ; i = nxt[i]){
- int j = point[i];
- if(vis[j]){flag = true;vis[s] = ;return;}
- dfs(j);
- if(flag){vis[s] = ;return;}
- dis[s] = max(dis[s],dis[j]+);
- }
- vis[s] = ;
- }
- int main(){
- scanf("%d%d",&n,&m);
- for(int i = ; i <= n ; ++ i)scanf("%s",s[i]+);
- int cnt = ;
- for(int i = ; i <= n ; ++ i){
- for(int j = ; j <= m ; ++ j){
- id[i][j] = ++ cnt;
- }
- }
- init();
- for(int i = ; i <= n ; ++ i){
- for(int j = ; j <= m ; ++ j){
- for(int k = ; k < ; ++ k){
- int dx = i + xx[k];
- int dy = j + yy[k];
- if(dx < || dx > n || dy < || dy > m)continue;
- if(s[i][j] == 'D' && s[dx][dy] == 'I')add(id[i][j],id[dx][dy]);
- if(s[i][j] == 'I' && s[dx][dy] == 'M')add(id[i][j],id[dx][dy]);
- if(s[i][j] == 'M' && s[dx][dy] == 'A')add(id[i][j],id[dx][dy]);
- if(s[i][j] == 'A' && s[dx][dy] == 'D')add(id[i][j],id[dx][dy]);
- }
- }
- }
- int ans = ;
- for(int i = ; i <= n ; ++ i){
- for(int j = ; j <= m ; ++ j){
- if(s[i][j] != 'D')continue;
- dfs(id[i][j]);
- if(flag == true){
- printf("Poor Inna!\n");
- return ;
- }
- if(dis[id[i][j]] > ans)ans = dis[id[i][j]];
- }
- }
- ans /= ;
- if(ans)printf("%d\n",ans);
- else printf("Poor Dima!\n");
- return ;
- }
cf374C Inna and Dima dfs判环+求最长链的更多相关文章
- HDU 4612 Warm up tarjan缩环+求最长链
Warm up Problem Description N planets are connected by M bidirectional channels that allow instant ...
- cf1278D——树的性质+并查集+线段树/DFS判环
昨天晚上本来想认真打一场的,,结果陪女朋友去了.. 回来之后看了看D,感觉有点思路,结果一直到现在才做出来 首先对所有线段按左端点排序,然后用并查集判所有边是否联通,即遍历每条边i,和前一条不覆盖它的 ...
- Atcoder Grand Contest 032C(欧拉回路,DFS判环)
#include<bits/stdc++.h>using namespace std;int vis[100007];vector<int>v[100007];vector&l ...
- LG2272/BZOJ1093 「ZJOI2007」最大半连通子图 Tarjan缩点+DAG求最长链
问题描述 LG2272 BZOJ1093 题解 观察半联通的定义,发现图中的一些结点,构成的链一定是一个半联通子图. 此时存在的环可能会干扰求解,于是\(\mathrm{Tarjan}\)缩点. 于是 ...
- Codeforces 374 C Inna and Dima (DFS)
Inna and Dima 题意:从图上的任意一个D点按着DIMADIMA的顺序走,问一共可以经过多少个DIMA,如果经过0个DIMA就输出“Pool DIma!“,如果可以有无数多个DIMA就输出” ...
- 【题解】CF374C Inna and Dima
题面传送门 解决思路 本题是找最长路的图上问题,所以先考虑如何建图. 首先把每一个字母转化为数字,然后对于每一个点枚举四个方向,如果有下一个字母,就向那个点建一条边,可以用 \(vector\) 存图 ...
- UVA818-Cutting Chains(二进制枚举+dfs判环)
Problem UVA818-Cutting Chains Accept:393 Submit:2087 Time Limit: 3000 mSec Problem Description Wha ...
- 洛谷2444(Trie图上dfs判环)
要点 并没问具体方案,说明很可能不是构造. 思考不断读入这个文本串,然后中间不出现某些文法的串.啊,这就是个自动机. 将不合法串使用ac自动机构成一个Trie图,我们需要的字符串就是在这个自动机上无限 ...
- CodeForces-1217D (拓扑排序/dfs 判环)
题意 https://vjudge.net/problem/CodeForces-1217D 请给一个有向图着色,使得没有一个环只有一个颜色,您需要最小化使用颜色的数量. 思路 因为是有向图,每个环两 ...
随机推荐
- 使用Python统计函数绘制复杂图形matplotlib
一.堆积图 1.堆积柱状图 如果将函数bar()中的参数bottom的取值设定为列表y.列表y1代表另一个数,函数bar(x,y1,bottom=y,color="r")就会输出堆 ...
- Java作业:第一次过程性考核 ——长春职业技术学院 16级网络工程
Java作业:第一次过程性考核 ••<结构化程序设计>•• 考核目标:初步了解Java基本语法规则,学习结构化程序设计思想. 码云链接:https://gitee.com/SoridoD/ ...
- JavaScript “函数重载”
函数重载(function overloading)必须依赖两件事情:判断传入参数数量的能力和判断传入参数类型的能力. JavaScript的每个函数都带有一个仅在这个函数范围内作用的变量argume ...
- JAVAEE 第六周
JSF 生命周期: FacesServlet 充当用户和 JSF 应用程序之间的纽带.它在明确限定的 JSF 生命周期(规定了用户请求之间的整个事件流)的范围内工作. 1. 当JSF页面上的一个事 ...
- jmeter如何进行MQTT性能测试(测试前期准备一,性能测试需求)
接到一个有关MQTT的性能测试任务,把查找资料到解决问题的过程都记录.分享下 首先先科普下性能测试中相关术语的解释及 说到性能测试.负载测试.压力测试.并发测试,很多人都是混合使用,或者一会叫压力测试 ...
- 2D 加速图形界面开发源代码亲写 想买来学习得加qq 313244484 20万当前代码,完整400万包写完
#include "StdAfx.h" #include "GUIFrame.h" #include <stdlib.h> #include < ...
- JSON与JS对象的区别
<script> var obj2={};//这只是JS对象 var obj3={width:100,height:200};/*这跟JSON就更不沾边了,只是JS的 对象 */ var ...
- java基础知识—运算符和基本选择结构
1.保存真假,使用boolean变量 boolean有两个值:true 真 false 假 2.从控制台接受输入信息,通过创建扫描器 Sacnner input=new Sacnner(System. ...
- vue项目中,使用vue-awesome-swiper插件实现轮播图
一.安装 npm install vue-awesome-swiper 二.项目中引入 import 'swiper/dist/css/swiper.css'import {swiper,swiper ...
- linux中sed命令批量修改
sed命令下批量替换文件内容 格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 -rl 路径` 文件名 -i 表示inplace edit,就地修改文件 ...