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 请给一个有向图着色,使得没有一个环只有一个颜色,您需要最小化使用颜色的数量. 思路 因为是有向图,每个环两 ...
随机推荐
- css flex布局,小程序flex布局,垂直居中完美解决
flex弹性布局,很好的解决了垂直居中的问题,上代码: wxml: <view class='container'> <view class='item item1'>item ...
- Java容器解析系列(7) ArrayDeque 详解
ArrayDeque,从名字上就可以看出来,其是通过数组实现的双端队列,我们先来看其源码: /** 有自动扩容机制; 不是线程安全的; 不允许添加null; 作为栈使用时比java.util.Stac ...
- HTML 基于 Python 实现分页功能
前面的话: 1. 网页引用的bootstrap 中的表格,所以需要引入样式类 2. 第一次写文章,不喜勿喷.有不足的地方,可留言我改正,在此先谢过. HTML代码: <!DOCTYPE html ...
- asp类型转换函数汇总 转贴
abs(number) 返回绝对值. array(arglist) 创建一个数组. asc(string) 返回字符串第一个字符的ansi码. atn(number) 返回反正弦值. cbool (e ...
- shell中脚本与函数的使用策略
脚本:运行的副作用不影响父环境,开辟了fork子进程; 函数:副作用,定义的变量,数据默认直接添加到了调用者的环境,也是它自己的环境;不想副作用影响调用者环境,就必须主动用local修饰; shell ...
- Python02(Linux命令)
Trainning-day01回顾 1.who :查看登录到系统的用户信息 2.pwd :查看当前所在路径 3.ls :查看当前目录的内容 ls -l ls -a ls -la / ls -l -a ...
- vue created中初始化属性
created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图. mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作
- NHibernate4使用Oracle.ManagedDataAccess.dll连接oracle及配置多个数据库连接
NHibernate数据库配置参数在hibernate.cfg.xml中 <?xml version="1.0" encoding="utf-8"?> ...
- VBA在WORD应用中如何将格式应用于选定内容
下列示例使用 Selection 属性将字符和段落格式应用于选定文本.使用 Font 属性获得字体格式的属性和方法,使用 ParagraphFormat 属性获得段落格式的属性和方法. Sub For ...
- Python成长之路【第四篇】模块儿
模块儿&包(* * * * *) 模块儿(modue)的概念 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多 ...