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 请给一个有向图着色,使得没有一个环只有一个颜色,您需要最小化使用颜色的数量. 思路 因为是有向图,每个环两 ...
随机推荐
- 有关@NgModule装饰器巩固
declarations —— 该应用所拥有的组件. imports —— 导入 BrowserModule 以获取浏览器特有的服务,比如 DOM 渲染.无害化处理和位置(location). pro ...
- Linux内核数据结构之kfifo详解
本文分析的原代码版本: 2.6.24.4 kfifo的定义文件: kernel/kfifo.c kfifo的头文件: include/linux/kfifo.h kfifo是内核里面的一个First ...
- servlet获取request数据的乱码解决
例如请求中有: /score?type=Mana&name=${user.name} ***************************************************** ...
- form表单提交到Servlet后,弹出对话框,然后在跳转页面
在Servlet中添加一下代码即可 out.print("<script>alert('添加成功!');window.location='index.jsp';</scri ...
- ffmpeg使用示例
/* 视频格式转换 ffmpeg -i "F:\Test\1.mp4" -y -vcodec copy -acodec copy "F:\Test\11.avi" ...
- 关于js数组的简单复制
var a=[]; a.push(1); a.push(2); a.push(3); var b=a; b[0]=4; alert(a);//4,2,3 alert(b);//4,2,3 这种写法由于 ...
- js 发送http请求
// 1.创建 XHR对象(IE6- 为ActiveX对象) // 2.连接及发送请求 // 3.回调处理 function createXMLHttpRequest() { var xhr; ...
- HTML中data-* 属性
使用 data-* 属性来嵌入自定义数据: <ul><li data-animal-type="bird">Owl</li><li dat ...
- C# 泛型反射的调用
namespace ConsoleApplicationFan_fan{ class Program { static void Main(string[] args) { //获取类型 Consol ...
- 信息技术手册可视化进度报告 基于BeautifulSoup框架的python3爬取数据并连接保存到MySQL数据库
老师给我们提供了一个word文档,里面是一份信息行业热词解释手册,要求我们把里面的文字存进数据库里面,然后在前台展示出来. 首先面临的问题是怎么把数据导进MySQL数据库,大家都有自己的方法,我采用了 ...