博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
转发帖子链[CodeForces-522A]
阅读量:4552 次
发布时间:2019-06-08

本文共 2559 字,大约阅读时间需要 8 分钟。

Reposts[CodeForces-522A]

VK Cup 2015 - Qualification Round 1

时间限制 1000ms 内存限制  256MB

这道题主要是求最大遍历深度,不难想到用DFS解。这道题数据量不大,暴搜可以直接过,所以本身题目没啥难度,只是建图的时候要用map处理一下字符串和图的顶点的对应关系。但是自己的DFS写的真叫一个狗屎,索性好好分析一下DFS的整个过程,来作为这道题的题解。

在算法导论书中,给出了进行DFS所需要的必备的储存信息:

当前顶点需要一个前驱$v.π$,用来跟踪DFS结束时构成的深度优先树。,当前顶点被访问到的时间戳$v.d$和完全访问后染成黑色的时间戳$v.f$(实际上,$v.d$也可以理解为跟源节点到当前位置的距离有关,也就是和深度有关,而$v.f$是回溯时才记录,跟深度就不好相关了。),除此之外,还需要一个染色$v.color$,用来记录当前顶点的颜色。其实这个染色的属性是用来判断当前节点走没走过,在算导书中提及,染色节点只要包括两种颜色就行了,因此实际上只需要一个布尔值。

DFS的开始,是在给定的图$G(V,E)$中,选择每一个可能的顶点,也就是$∀u∈G.V$,依次进行DFS。二叉树的DFS遍历,其实就是图的DFS的特例,因为二叉树的起始顶点只有树根。在DFS过程中,设当前顶点为$u$,先将$u$染色为$black$($u.color=black$),然后选择所有有边连接的顶点$∀u′∈G:Adj[u]$,判断是否被染色,对于没有染色,也就是没有走过的顶点继续进行DFS,直到没有顶点可以走为止。没有顶点可以走,意味着所有的顶点都被染色了,或者直接这个顶点没有连接任何下一个顶点。实际上,在上述描述的DFS过程中,无需额外设置递归的出口,因为选择合法的$u′$已经暗含了递归出口。需要注意,当DFS子过程回溯到主体过程时,需要重置所有顶点的染色标记和前驱标记。

下面考虑具体实现的问题:一是图选择何种表示方法。通常情况下,稀疏图采用邻接表的方法,这样能够避免大量的空间浪费。因为采用邻接矩阵的方法,有$V$个顶点的图,就需要$V×V$的矩阵,也就是$V^2$的空间;并且搜索时,必须依次扫描当前顶点是不是存在着到别的顶点的边,因此总的时间复杂度是$O(V^2)$,在假定稀疏图$E<<V$的情况,邻接矩阵相较于邻接表的$O(V+E)$还是较慢的。对于邻接表中的表,通常的定义为链表,但是能够自由扩张的顺序数据结构都是可以的。因此我在做题的时候,采用了STL中的vector容器,来作为图的邻接表表示。至于染色属性的选择,既可以将图的每一个顶点定义成结构体,也可以单独设置数组,作为染色标记。我在这里采用了后一种的处理方法。

对于数组作为邻接表的表示方法,我一开始把下标搞混了,一直得不到正确的结果。以我写的DFS过程为例,id参数表示当前顶点,用一个循环遍历vector容器表示的邻接表寻找有边连接的下一个顶点,因此判断下一个顶点是否被染色时,gone数组的下标实际上是下一个顶点graph[id][i],而不是idi的任意一个,i在这里表示用vector容器实现的邻接表在当前为id的顶点所包含的相邻的第i个顶点。除此之外,试图将判重和记录深度用一个属性来表示,似乎并不可行。

下面给出我AC的完整代码,供参考。

 

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 map
mapper; 9 vector
graph[205];10 int gone[205];11 int n;12 int cnt = 0;13 int ans = -2;14 int proc(string & s)15 {16 for (int i = 0; i < s.size(); i++)17 if (s[i] >= 'A'&&s[i] <= 'Z')s[i] += 32;18 map
::iterator it = mapper.find(s);19 if (it == mapper.end())20 {21 mapper.insert(pair
(s, cnt));22 return cnt++;23 }24 return it->second;25 }26 void dfs(int id, int time)27 {28 gone[id] = 0;29 for (int i = 0; i < graph[id].size(); i++)30 {31 if(gone[graph[id][i]]!=-1||graph[graph[id][i]].empty())32 {33 ans = max(ans, time + 1);34 return;35 }36 dfs(graph[id][i], ++time);37 }38 }39 int main()40 {41 cin >> n;42 string tmp1, tmp2;43 while (n--)44 {45 cin >> tmp1;46 cin >> tmp2;47 cin >> tmp2;48 int id1 = proc(tmp1);49 int id2 = proc(tmp2);50 graph[id1].push_back(id2);51 }52 for (int i = 0; i < cnt; i++)53 {54 for (int j = 0; j < 205; j++)gone[j] = -1;55 dfs(i, 0);56 }57 cout << ans + 1;58 return 0;59 }

 

 

 

 

 

 ,

转载于:https://www.cnblogs.com/ggggg63/p/6767831.html

你可能感兴趣的文章
【Uva 1252】Twenty Questions
查看>>
1_访问命令行
查看>>
File操作相关
查看>>
Linux:文本处理工具
查看>>
java,for穷举,经典题目,百鸡百钱
查看>>
Solr4.7从文件创建索引
查看>>
6.9-LV/XML机器人数据存储
查看>>
Django ajax 发送post请求 前端报错解决
查看>>
About Me
查看>>
Android视频处理 --处理视频第一帧缩略图
查看>>
IOS中如何判断APP是否安装后首次运行或升级后首次运行
查看>>
关于反射
查看>>
全面解析构建私有云的两大核心架构组件
查看>>
在phpWeChat中如何定义一个授权登录(获取昵称)的链接
查看>>
python 符合条件跳过下一次循环
查看>>
mysql提示Column count doesn't match value count at row 1错误
查看>>
笑话,难道懂礼貌就必须说谎吗
查看>>
MySQL(二)
查看>>
第四章 –– 多态的概念
查看>>
C#中this的 四种 用法
查看>>