随笔分类 - 数据结构与算法
摘要:2012-01-30 18:06:16|分类:程序|字号订阅在北京冬令营的时候,yby提到了“带花树开花”算法来解非二分图的最大匹配。于是,我打算看看这是个什么玩意。其实之前,我已经对这个算法了解了个大概,但是。。。真的不敢去写。有一个叫Galil Zvi的人(应该叫计算机科学家),写了篇论文:Efficient Algorithms for Finding Maximal Matching in Graphs(如果你在网上搜不到,可以:http://builtinclz.abcz8.com/art/2012/Galil%20Zvi.pdf)这篇论文真神啊,它解决了4个问题:(一般图+二分图)
阅读全文
摘要:后缀数组——处理字符串的有力工具作者:罗穗骞2009年1月 【摘要】 后缀数组是处理字符串的有力工具。后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现,能够实现后缀树的很多功能而时间复杂度也并不逊色,而且它比后缀树所占用的内存空间小很多。可以说,在信息学竞赛中后缀数组比后缀树要更为实用。本文分两部分。第一部分介绍两种构造后缀数组的方法,重点介绍如何用简洁高效的代码实现,并对两种算法进行了比较。第二部分介绍后缀数组在各种类型题目中的具体应用。 【关键字】 字符串,后缀,后缀数组,名次数组,基数排序, 【正文】一、后缀数组的实现 本节主要介绍后缀数组的两种实现方法:倍增算...
阅读全文
摘要:题意: 莱克尔和她的朋友到公园玩,公园很大也很漂亮。公园包含n个景点通过n-1条边相连。克莱尔太累了,所以不能去参观所有点景点。经过深思熟虑,她决定只访问其中的k个景点。她拿出地图发现所有景点的入口都很特殊。所以她想选择一个入口,并找到一条最短的路来参观k个景点。我们假设景点之间的距离为1。解题思路:因为地图形状为树形,所以求树的最大直径。当k小于等于直径的时候输出k-1,当k大于直径的时候,因为访问了某一个景需要返回直径所在的路径上,所以当k大于冷的时候结果为len-(k-len-1)*2。#include #include #include #include #include using
阅读全文
摘要:伸展树(Splay Tree)是AVL树不错的替代,它有以下几个特点:(1)它是二叉查找树的改进,所以具有二叉查找树的有序性。(2)对伸展树的操作的平摊复杂度是O(log2n)。(3)伸展树的空间要求、编程难度非常低。提到伸展树,就不得不提到AVL树和Read-Black树,虽然这两种树能够保证各种操作在最坏情况下都为logN,但是两都实现都比较复杂。而在实际情况中,90%的访问发生在10%的数据上。因此,我们可以重构树的结构,使得被经常访问的节点朝树根的方向移动。尽管这会引入额外的操作,但是经常被访问的节点被移动到了靠近根的位置,因此,对于这部分节点,我们可以很快的访问。这样,就能使得平摊复
阅读全文
摘要:#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;#define LL long long#define pii pair#define bug coutr) return ; int m=(r+l)>>1; newNode(x,m); makeTree(ch[...
阅读全文
摘要:题目地址:http://poj.org/problem?id=2513题意就是给我们n个带颜色的木棍,看是否能排成一排(相接的颜色必须是一样的),解题思路是看的别人的:判断无向图中是否存在欧拉通路,判断条件是:1、有且只有两个度为奇数的节点2、图是连通的由于节点是字符串,因此我们可以利用字典树将其转换成一个颜色序号。这样,统计每种颜色的出现次数就可以了。判断图是否连通,可以利用并查集:若最后所有节点在同一个集合,则图是连通的。#include#include#include#define maxn 501000int father[maxn],degree[maxn];struct node{
阅读全文
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1247本题为简单字典树问题。解题思路:进行插入的时候,使用flg标记每个单词的结尾,当flg为true时表示到了某一个单词的结尾当为false时即不是某一个单词的结尾。进行查找的时候当一个单词的前一部分是某个单词的时候则判断后面一部分是否也是一个已经存在的单词,是则返回true否则返回false。#include#include#includechar list[50001][26];struct node{ bool flg; node *next[26];}*root;void insert(c
阅读全文
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1251字典树模版题动态实现:#include#include#include#define maxn 26struct node{ int count; node *next[maxn];}*root;void insert(char str[]){ int i,len = strlen(str); node *current,*newset; current = root; for(i = 0; i next[k] != NULL) { current = current->next[k];
阅读全文
摘要:题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3999本题为简单二叉排序树,先按排序树创建树,然后先序遍历二叉树,输出的时候最后一个数字后面没有空格。数组实现:#include#include#define N 100005int tree[N],left[N],right[N],a[N],num,flg;//tree数组用来保存树节点的值,left,right数组用来保存结点的左右子树,void insert(int index,int x){ if( x #includestruct node{ int data; struct node *
阅读全文
摘要:最近发现自己在高级数据结构方面好薄弱的,于是看了很多文档,发现这篇不错。数据结构——堆的操作和实现当应用优先级队列或者进行堆排序时,一般利用堆来实现。堆是一个完全(除最底层外都是满的)二叉树,并满足如下条件:1、根结点若有子树,则子树一定也是堆。2、根结点一定大于(或小于)子结点。因为要求堆必须是完全二叉树,所以可以用线性的数据结构,比如数组,来实现堆。利用数组实现,则对于长为N的堆中的元素从0到N-1排列,有:i的父结点:Parent(i)=(i+1)/2-1i的左叶子:Left(i)=(i+1)*2-1i的右叶子:Right(i)=(i+1)*2堆的操作主要以一个“堆化”(Heapify)
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1162#include#includebool P[110];//标记数组,标记某一个点是否已经连接到树上struct point{ double x,y;}Point[110],A[110];double SegLen(point a,point b){ return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}int main(){ int n,i,num,j; int Min; //Min表示第Min个点到已经连接...
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1863最小生成树kruskal算法:http://www.zhuoda.org/irini/78592.html一开始看到题目的时候就知道是求最小生成树的题目,而且可以用并查集了构建树,但是不知道怎么将并查集和求最小生成树的算法结合起来,后来看到了最小生成树Kruskal算法是用贪心求最小生成树的,每次都都取权值最小的边去构建树,如果两点的祖先结点相同,及直接连通或者间接连通的时候则不再建边否则创建边使连点直接或间接连通。实现算法如下:#include#include#include#define MA
阅读全文
摘要:题目:http://acm.hdu.edu.cn/showproblem.php?pid=1166基维百科:http://zh.wikipedia.org/wiki/%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84http://duanple.blog.163.com/blog/static/7097176720081131113145832/树状数组源码及部分注释:#include#include#define MAX 50010int N;int per[MAX],C[MAX];int lowbit(int n){//此函数实际就是将n的二进制表示形式留下最右边的1
阅读全文
摘要:好久没写过算法了,添一个吧,写一个线段树的入门知识,比较大众化。上次在湖大,其中的一道题数据很强,我试了好多种优化都TLE,相信只能用线段树才能过。回来之后暗暗又学了一次线段树,想想好像是第三次学了,像网络流一样每学一次都有新的体会。把问题简化一下:在自然数,且所有的数不大于30000的范围内讨论一个问题:现在已知n条线段,把端点依次输入告诉你,然后有m个询问,每个询问输入一个点,要求这个点在多少条线段上出现过;最基本的解法当然就是读一个点,就把所有线段比一下,看看在不在线段中;每次询问都要把n条线段查一次,那么m次询问,就要运算m*n次,复杂度就是O(m*n)这道题m和n都是30000,那么
阅读全文

浙公网安备 33010602011771号