
Adnvanced Algo & DS 高级算法和数据结构
文章平均质量分 86
靖心
降低成功的时间复杂度,提高生活的空间复杂度
专注,努力不会白费的!
展开
-
POJ 1511 Invitation Cards 图论题解
DescriptionIn the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique原创 2014-11-24 18:25:40 · 1313 阅读 · 0 评论 -
HDU 4107 Gangster Segment Tree线段树
这道题也有点新意,就是需要记录最小值段和最大值段,然后成段更新这个段,而不用没点去更新,达到提高速度的目的。本题过的人很少,因为大部分都超时了,我严格按照线段树的方法去写,一开始居然也超时。然后修补了两个地方就过了,具体修改的地方请参看程序。知道最大值段和最小值段,然后修补一下就能过了。不是特别难的题目。#include #include #include using na原创 2014-06-20 16:54:44 · 944 阅读 · 0 评论 -
HDU 1251 统计难题 Trie题解
基本上是标准的寻找前缀的问题,只需要insert和search函数就可以了。我这里主要是修改一下n的记录方法,这里的n代表的不是叶子节点的标志,而是有多少单词经过了这条路径的标志。然后是查找需要查找的前缀单词,如果没有找到,就返回0,表示没有单词以这个前缀单词为前缀,如果找到,直接返回n就是答案了。因为有n个单词经过了这条路径。查找效率是常数。使用静态分配空间的办法。#原创 2014-08-04 19:20:18 · 1273 阅读 · 0 评论 -
HDU 1010 Tempter of the Bone heuristic 剪枝法
本题就是考剪枝法了。应该说是比较高级的应用了。因为要使用heuristic(经验)剪枝法。要总结出这个经验规律来,不容易。我说这是高级的应用也因为网上太多解题报告都没有分析好这题,给出的程序也很慢,仅仅能过掉,由此看来很多人没有做好这道题。这里我需要更正一下网上流行的说法:奇偶剪枝法。其实本题使用奇偶剪枝法并不能太大提高速度,只能说仅仅让使用奇偶剪枝过掉。所以网上说本题使用奇偶剪枝的,其实并不能提高速度。原因:奇偶剪枝只能剪枝一次,不能在递归的时候剪枝,因为只要初始化位置符合奇偶性,那么之后的任原创 2014-06-19 21:10:58 · 928 阅读 · 0 评论 -
POJ 2418 Hardwood Species Trie解法
计算一个字符串数组中有多少个重复字符串出现。如果直接使用map容器,那么这条题就很简单了,一下就AC了,因为map已经处理好一切了;不过时间超过1532ms,有点慢。如下:int main(){ map msi; int total = 0; char treeName[40]; while (gets(treeName)) { msi[treeName]++;原创 2014-07-28 21:01:32 · 1160 阅读 · 0 评论 -
HDU 2444 The Accomodation of Students二分图判定和匈牙利算法
本题就是先判断是否可以组成二分图,然后用匈牙利算法求出最大匹配。到底如何学习一种新算法呢?我也不知道什么方法是最佳的了,因为看书本和大牛们写的匈牙利算法详细分析,看了差不多两个小时没看懂,最后自己直接看代码,居然不到半个小时看懂了。然后就可以直接拿来解题啦。比如topcoder上有这个算法的很详细的分析,真没看懂。代码居然比分析更清晰了?我也不好下结论。但是我觉原创 2014-06-19 14:28:35 · 1094 阅读 · 0 评论 -
HDU 1068 Girls And Boys 二分图题解
选择出一组学生,这组学生里面不能彼此之间有过恋爱史的。又是一个典型的二分图问题。不过需要把所有学生看成一组*2,然后求最大匹配,然后除以2. 这样其实建图的时候,建成有向图也是可以的了。而且也是给出了两个方向的点了。注意本题没有给出最大数是多少学生了,所以最好使用动态分配内存了。而且本题的输入处理也特别点,要处理好,用好scanf这个函数。原创 2014-06-20 09:48:29 · 1597 阅读 · 0 评论 -
HDU 2063 过山车 二分图题解
一个男女搭配的关系图,看可以凑成多少对,基本和最原始的一个二分图谜题一样了,就是 一个岛上可以凑成多少对夫妻的问题。所以是典型的二分图问题。使用匈牙利算法,写成两个函数,就非常清晰了。本程序还带分配释放程序,当然oj一般不需要。但是好的程序一定要。#include #include int K, M, N, a, b;int *linker;bool **gra, *use原创 2014-06-20 08:57:02 · 1130 阅读 · 0 评论 -
HDU 1075 What Are You Talking About Trie题解
翻译火星语,不过火星语也是使用英文单词的,就是把一个单词对应到另外一个单词。可以使用map, 使用二分,方法很多。不过最快的应该都是Trie解法了。把火星语挂在Trie树中,然后在叶子节点增加一个string容器,装英语单词。查找的时候,找到了出现在Trie中的火星语,就返回string就可以了。#include #include #include using n原创 2014-08-04 10:09:30 · 1083 阅读 · 0 评论 -
POJ 2914 Minimum Cut 最小割算法题解
最标准的最小割算法应用题目。核心思想就是缩边:先缩小最大的边,然后缩小次大的边,依此缩小基础算法:Prime最小生成树算法不过本题测试的数据好像怪怪的,同样的算法时间运行会差别很大,而且一样的代码替换,居然会WA。系统出错的几率很小,难倒测试系统本题会有错误?懒得继续测试这道题的系统了,反正算法正确,AC。#include #include #include c原创 2014-07-10 14:48:44 · 1545 阅读 · 0 评论 -
HDU 3635 Dragon Balls 七龙珠 Union Find算法
孙悟空要寻找七龙珠,这回是七龙珠的增强版了,因为这些龙珠会衍生,最后不止七颗龙珠了。悟空带着布玛的龙珠雷达探测器出发了,却发现布玛的龙珠雷达探测器的程序太垃圾了,所以找到我们这些ACM高手为龙珠雷达探测器写个程序,要求可以显示某颗龙珠所在的城市的位置,该龙珠所在的城市共有多少颗龙珠,龙珠移动过的次数。布玛是个有钱人啊,写个程序我要价5百万,不算过分吧。因为本程序需要用到Union Find原创 2014-07-27 23:51:34 · 1442 阅读 · 0 评论 -
POJ 1470 Closest Common Ancestors LCA题解
本题也是找LCA的题目,不过要求多次查询,一般的暴力查询就必然超时了,故此必须使用更高级的方法,这里使用Tarjan算法。本题处理Tarjan算法,似乎输入处理也挺麻烦的。注意: 因为查询的数据会极大,故此使用一个数组记录所有查询数据就会超时的。我就载在这里了。查了好久才想到这点。因为我使用了一个vector容器记录了查询数据,故此每次都循环这组这么大的数据,就超时了。----解决办法:使原创 2014-07-08 19:24:03 · 928 阅读 · 0 评论 -
SPOJ 15. The Shortest Path 最短路径题解
本题就是给出一组cities,然后下面会询问,两个cities之间的最短路径。属于重复询问的问题,暂时我只想到使用Dijsktra+heap实现了。因为本题重复查询次数也不多,故此如果保存所有最短路径,那么是得不偿失了。所以还是重复使用Dijsktra吧。有没有更加好的办法处理重复查询问题呢?还没想到。本算法纯粹手工打造了,不使用stl,代码很长很长,光打一遍就会手软的,呵呵。原创 2014-06-17 12:29:46 · 1625 阅读 · 0 评论 -
Geeks Ford-Fulkerson Algorithm for Maximum Flow Problem 最大网络流问题
很久之前就想攻克一下网络流的问题了,一直拖着,一是觉得这部分的内容好像非常高级,二是还有很多其他算法也需要学习,三是觉得先补补相关算法会好点不过其实这虽然是图论比较高级的内容,但是基础打好了,那么还是不会太难的,而且它的相关算法并不多,熟悉图论之后就可以学习了,就算法不会二分图也可以学习。这里使用Ford-Fulkerson算法,其实现的方法叫做:Edmonds-Karp原创 2014-07-26 15:19:34 · 2017 阅读 · 0 评论 -
POJ 1002 487-3279 Trie题解
本题的解法是多种多样的,这里使用Trie来解决一下。也可以使用hash表,map等解法,因为输入是特定的7位数字,故此应该都可以解决的。这里使用Trie的速度并不快,主要是因为最后我直接遍历输出,遍历整个Trie的速度还是比较慢的。思路:1 使用insert函数建立Trie,主要增加一个叶子节点的信息,记录当前有多少个重复的字符串2 遍历就是根据叶子节点的信息决定是否需要输出。原创 2014-07-28 13:23:58 · 1033 阅读 · 0 评论 -
HDU 3549 Flow Problem 最大网络流
本题也是典型的最大流题解。很好理解最大流建议大家还是去看 Introduction to algorithm这本经典书。这里题解的特点是: 1 使用静态邻接表建图2 建立双向图,以便增加逆向流。3 合并重复边优化图使用邻接表解决网络流的关键是第二点。一开始一直都看不明白为什么需要逆向增加流,很多博客也是一句话概括掉了,故此还是看书比较能弄懂。推荐看书,这里不重复了。原创 2014-07-26 21:13:50 · 886 阅读 · 0 评论 -
HDU 1698 Just a Hook 线段树解法
很经典的题目,而且是标准的线段树增加lazy标志的入门题目。做了好久线段树,果然是practice makes perfect, 这次很畅快,打完一次性AC了。标志的线段树函数。主要是:更新的时候只更新到需要的节点,然后最后的时候一次性把所以节点都更新完毕。这也是线段树常用的技术。#include const int SIZE = 100005;struct Node原创 2014-06-15 21:30:09 · 779 阅读 · 0 评论 -
HDU 1269 迷宫城堡 最大强连通图题解
寻找一个迷宫是否是只有一个最大强连通图。使用Tarjan算法去求解,经典算法,必须要学习好,要自己创造出来是十分困难的了。参考资料:https://www.byvoid.com/blog/scc-tarjan/const int N = 10001;vector gra[N];stack stk;bool inStack[N];int dfsNum[N];int backT原创 2014-06-21 22:14:18 · 1012 阅读 · 0 评论 -
POJ 3630 Phone List Trie题解
Trie的应用题目。本题有两个难点了:1 动态建立Trie会超时,需要静态建立数组,然后构造树2 判断的时候注意两种情况: 1) Tire树有133,然后插入13333556的时候,2)插入顺序倒转过来的时候修改一下标准Trie数的插入函数就可以了:#include #include const int MAX_NODE = 100001;const int M原创 2014-08-04 16:44:22 · 1112 阅读 · 0 评论 -
POJ 2914 Minimum Cut 最小割图论
本题是06年百度之星半决赛的题目,图论的最小割问题,算是图论高级内容吧。Stoer Wager算法,其中的难点是:1 逐条边查找最大的边的权值-过程有点想Prime算法,不过实际上不是Prime算法,因为目的并不是最大生成树,而是需要把一个顶点的所有边都加起来,把这些边去掉,就是这个顶点的割点值了。那么就需要遍历整个图,到了最后一个节点才能保证是找到了这个节点的所有边。2 缩点:所谓缩点就是把最后一个节点去掉,同时保留其边值信息,实际就是保留这个顶点的和其他顶点相连的最小边值。比较难理解的,一般写这原创 2014-11-04 08:01:25 · 2270 阅读 · 0 评论 -
SPOJ 15. The Shortest Path 堆优化Dijsktra
You are given a list of cities. Each direct connection between two cities has its transportation cost (an integer bigger than 0). The goal is to find the paths of minimum cost between pairs of cities.原创 2014-10-04 23:32:20 · 1704 阅读 · 0 评论 -
POJ 2553 The Bottom of Graph 强连通图题解
题意的本质是查找没有出度的强连通子图,没有出度就是sink,the bottom of graph了。就是利用Tarjan算法求强连通子图,并要用标识号标识各个强连通子图,然后记录好各个顶点属于哪强连通子图。程序带详细的注解:原创 2014-10-31 09:22:47 · 1257 阅读 · 0 评论 -
POJ 1236 Network of Schools 强连通图
图论题目,需要解决问题:1 使用Tarjan算法求子强连通图2 标识顶点属于哪个子强连通图3 计算各个子强连通图的零入度数和零出度数图论中高级内容了,是有点难度的,不细心一点肯定会出错的。这次本博主认真注解好几乎每个语句,希望大家可以follow我的程序。原创 2014-10-26 16:43:05 · 1586 阅读 · 1 评论 -
POJ 1860 Currency Exchange BellmanFord题解
会建图,然后使用标准的Bellman Ford算法,判断负环就解决了。不过本题实际应用不是计算负环,而是计算最大值,也就是求出源点到所有点的最大收益值之后,然后判断是否可以进一步增加收益,如果可以那么证明有环可以不断反复走这个环,不断增加收益,实际就是判负环的应用了。#include #include #include #include #include #include原创 2014-09-02 09:52:41 · 1664 阅读 · 0 评论 -
Codeforces 464 C. Substitutes in Number 动态规划法题解
本题使用动态规划法思想。因为需要一步一步地替换相对应的数字的,如果直接模拟,那么就需要大量插入和删除操作,最快也需要lg(n)的效率,但是最后数列就会变得非常长,这样最后计算结果遍历一次也会超时的。故此使用数据结构加速替换操作,并不是好办法。这就使用动态规划法从后往前替换,相当于路径压缩了,一步直接把数字替换成最终结果的数字。也要记录好每个数字最终替换成多少个数位,以便正确计算结果。可以画树来模拟一下替换操作,那么从叶子节点往根节点替换数字,把所有的路径都直接压缩起来。原创 2014-09-08 17:47:34 · 2003 阅读 · 0 评论 -
HDU 1045 Fire Net 二分图Bipartite题解
本题可以使用DFS直接爆搜出答案,不过这样类型的题目其实是个二分图的题解。这个二分图,难不在Hungary算法,而是难在于建图。需要挺高的抽象思维的。建图:1 把同一行不被X分开的格子标同一个号码,被X分开的标下一个号码,这样做是为了缩点,不需要把所有的格子都分开标号,而且可以更方便建个更加小的图。2 同理把同一列的格子标号3 然后判断相同一个格子的行标号和列标号是有路径的,其原创 2014-08-22 23:13:49 · 1207 阅读 · 0 评论 -
HDU 2896 病毒侵袭 AC自动机题解
本题是在text里面查找key word的增强版,因为这里有多个text。那么就不可以简单把Trie的叶子标志记录修改成-1进行加速了,可以使用其他技术,我直接使用个vis数组记录已经访问过的节点,达到加速效果,速度还算挺快的。不过看discuss里面有人直接使用Trie,做出了140ms的速度,而且他的程序严格来说并不正确,可见本题的数据很水啊。Trie的时间效率肯定比AC自动机低,但是原创 2014-08-07 20:07:08 · 1186 阅读 · 0 评论 -
HDU 3065 病毒侵袭持续中 AC自动机题解
其实本题比HDU的病毒侵袭1还简单,不过有一个陷阱卡到我了:就是搜索text的时候,当遇到的字母不是大写字母的时候,那么就要重新从根节点开始搜索,否则就会答案错误。那么一点陷阱,居然没想到啊。教训啊:看来对不太平常的地方,需要更加深入的思考,才能发现其中的陷阱,否则就WA了。#include #include #include using std::queue;con原创 2014-08-07 22:23:36 · 925 阅读 · 0 评论 -
POJ 3080 Blue Jeans Trie后缀树解法
题目是牛仔裤的意思,不过看不出题意和Blue Jeans有什么关系。本题的数据是很水的,数据量小,故此可以使用非常暴力的方法过,也可以使用不那么暴力的KMP过。这里使用更加不暴力的Trie后缀树过,这种解法就一点都不水了,呵呵。思路:1 建立所有字符串的后缀Trie树2 增加额外信息,看每过路径是否是所有的字符串都经过了,如果是,那么就是合法的字符串了,查找最长的这样的字符串原创 2014-08-03 08:15:47 · 1433 阅读 · 0 评论 -
HDU 4006 The kth great number AVL解法
给出动态更新数据,实时问第K个大的数值是什么?利用AVL数据结构做的一个统计数,比较高级的数据结构内容了。不知道题目给出的数据值是否有重复,因为我下面的程序是可以处理出现数据重复的情况的。其中的奥妙是增加了repeat的信息,可以知道出现了当前数组多少次。主要是知道如何维护这些数据和如何查询,维护数据的函数是pushUp,查询函数是selectKth。其他就是一般的AVL操作。原创 2014-07-31 21:30:05 · 1006 阅读 · 0 评论 -
HDU 2222 Keywords Search AC自动机入门题
单词统计的题目,给出一些单词,统计有多少单词在一个文本中出现,最经典的入门题了。AC自动机的基础:1 Trie, 以这个数据结构为基础的,不过增加一个fail指针和构造fail的函数2 KMP,不是直接运用KMP,而是需要KMP的思想,KMP思想都没有的话,理解这个算法会更加吃力的。注意本题的单词会有重复出现的,一个单词只能统计一次。搜索了一下网上的题解,发现好多代码都原创 2014-08-07 10:25:08 · 1929 阅读 · 0 评论 -
POJ 1204 Word Puzzles AC自动机题解
AC自动机的灵活运用,本题关键是灵活二字。因为数据不是很大,时间要求也不高的缘故,所以本题有人使用暴力法也过了,有人使用Trie,然后枚举八个方向,也过了,不过速度很慢。当然有人使用AC自动机没AC的,在讨论区里喊AC自动机超时的,那是因为不会灵活运用,或者是硬套模板的,AC了速度也不会快。给出本人的算法思路:1 把需要查找的关键字建立Trie, 然后构造AC自动机2 查找的时候分八个方向查找,比如棋盘是board[N][M],那么就可以循环i(0->N-1),然后每次把board[i]当做一个原创 2014-08-07 15:35:34 · 1634 阅读 · 0 评论 -
Geeks - Range Minimum Query RMQ范围最小值查询
使用线段树预处理,可以使得查询RMQ时间效率在O(lgn)。线段树是记录某范围内的最小值。标准的线段树应用。Geeks上只有两道线段树的题目了,而且没有讲到pushUp和pushDown操作,只是线段树的入门了。参考:http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/我修改了一下他的程序,使用原创 2014-06-21 09:16:14 · 1442 阅读 · 2 评论 -
HDU 4760 Good FireWall 完善Trie题解
本题乍看像是线段树之类的区间操作,不过因为只是需要查找ip的前缀,故此其实是使用Trie来做。挺高难度的Trie应用,做完这道题之后说明Trie功力有一定火候了。这里的Trie使用到了Delete函数,这是个Trie函数中最难的函数了,当然要使用数组记录的方法水掉,也是可以的。这里不水,给出delete函数。考点难点:1 Trie的操作函数的灵活运用,主要难点是delete函数的灵活运用2 在叶子节点所有的group id, 删除的时候要注意,不能一气删除了,有多个group id会挂在同一颗树原创 2014-08-05 10:47:44 · 1172 阅读 · 0 评论 -
POJ 1511 Invitation Cards SPFA算法题解
本算法就是Bellman-ford的改进,SPFA即 Shortest Path Faster Algorithm.解析这个算法的博文不少,不过没有什么好的证明。我觉得这个算法之所以正确,是因为每次新增加一个所谓的松弛点,那么其他任何点值可能以该松弛点为中介点,才可能找到比原来更加短的路径,故此是正确的。当然这个不是正规的证明。不过仔细想想这个算法,的确是巧妙,而他的妙点,就是这里了。原创 2014-07-12 15:28:09 · 1000 阅读 · 0 评论 -
HDU 2255 奔小康赚大钱 KM算法题解
KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,因为Hungary算法是最大匹配的算法,不带权。经典算法,想不出来的了,要参考别人的。然后消化吸收吧。因为真的很复杂的算法。我理解算法匹配思想:1 开始的时候,所有边都记录自己的最优匹配,不管有没有冲突2 递归循环的时候,如果找不到自己的最优匹配,那么就找次要匹配3 次要匹配不行,继续找下一个次优匹配,所有原创 2014-07-07 14:21:25 · 1047 阅读 · 0 评论 -
Timus : 1002. Phone Numbers 题解
把电话号码转换成为词典中可以记忆的的单词的组合,找到最短的组合。我这道题应用到的知识点:1 Trie数据结构2 map的应用3 动态规划法Word Break的知识4 递归剪枝法原创 2014-06-02 15:28:34 · 1762 阅读 · 0 评论 -
POJ1258 Agri-Net MST最小生成树题解
搭建一个最小代价的网络,最原始的最小生成树的应用。这里使用Union find和Kruskal算法求解.注意:1 给出的数据是原始的矩阵图,但是需要转化为边表示的图,方便运用Kruskal,因为需要sort2 减少边,一个矩阵最多需要(N*N-N)>>1条边,有人讨论本题是否有向,那是无意义的,因为本题的最小生成树和方向无关。3 使用Union find是为了判断是否有环,比原原创 2014-06-28 09:21:05 · 1175 阅读 · 0 评论 -
POJ 1041 John's trip Euler欧拉回路判定和求回路
就是欧拉判定,判定之后就可以使用DFS求欧拉回路了。图论内容。这里使用邻接矩阵会快很多速度。这类题目都是十分困难的,光是定义的记录的数组变量就会是一大堆。#include #include #include #include using namespace std;struct Edge{ int ed, des; Edge(int e = 0, int d原创 2014-06-25 21:07:06 · 1204 阅读 · 0 评论 -
HDU 3049 Data Processing 数论题解
又是一条数论题目,最近学习数论,看完书本感觉并不能掌握数论的,还是需要多多练习,多运用才能掌握这个思想武器的。本题可以简单点过,不需要太高级的数论内容;但是也可以运用好数论的内容,可以应用上三个数论的内容:1 扩展欧几里得2 快速求模3 乘法逆元(inverse of modulo)2 快速求模,也可以生成一个数组,因为这里最大是40000,故此数值不大,可以使用数组,然后查表,速度很快。但是这里使用快速的时间效率也几乎接近常数,没必要保存一个数组。如下面的powMod函数。3 乘法原创 2014-06-08 13:58:51 · 1143 阅读 · 0 评论