摘要: 题意:分配问题,有F种食物,D种饮料,N头牛,每头牛有自己喜欢的吃的和喝的东西,现在让你去分配,使得吃喝都得到的牛最多。每种吃喝的东西只能招待一头牛。分析:把一头牛拆成两头,一头和食物连,一头和饮料连,当然这两头牛之间肯定要连一条边,添加一个源点汇点分别向食物和饮料连。这里把牛拆成两个点是为了限制进过牛的流最大为1,这样就可以通过求最大流来得到答案。举例说明为什么要拆牛:(见discuss)比如只有1条牛,1 2 两种食物,1 2两种水那图会是下边那样的食物1 食物2 | | | | -----> 牛 <---- / \ / \ 水1<--| |----> 水2对应的输 阅读全文
posted @ 2012-08-11 20:21 pushing my way 阅读(325) 评论(0) 推荐(0) 编辑
摘要: Edmonds-Karp算法是最简单的网络流算法,比较慢,时间复杂度为O(V*E^2)。具体思路可以参考算法导论。此算法用广度优先搜索寻找增光路的,代码写起来比较简单。代码:View Code 1 #include <iostream> 2 #include <queue> 3 #include <stdio.h> 4 #include <memory.h> 5 using namespace std; 6 const int maxnum=201; 7 const int maxdata=0x7fffffff; 8 int f[maxnum][ 阅读全文
posted @ 2012-08-09 17:10 pushing my way 阅读(684) 评论(0) 推荐(0) 编辑
摘要: 题意:经典的图的染色问题,求对于给定的无向图中,给每个结点染两种不同颜色(黑色和白色)的一种且相邻结点的颜色不同,求染成黑色的最多结点数。分析:这个题求的图的最大独立集,最大独立集即为黑色节点的个数。由于原图的最大独立集=补图的最大团。而这个题是普通图,所以用回溯法来做,时间复杂度O(n*2^n)代码:View Code 1 #include <iostream> 2 #include <memory.h> 3 #include <stdio.h> 4 using namespace std; 5 6 const int maxnum=101; 7 bool 阅读全文
posted @ 2012-08-09 10:37 pushing my way 阅读(1326) 评论(0) 推荐(0) 编辑
摘要: 题意:已知班级有g个女孩和b个男孩,所有女生之间都相互认识,所有男生之间也相互认识,给出m对关系表示哪个女孩与哪个男孩认识。现在要选择一些学生来组成一个团,使得里面所有人都认识,求此团最大人数。思路:最大团问题。定理:原图的最大团=补图的最大独立集原图的最大独立集=补图的最大团。由于这个题的补图显然是一个二分图,而二分图的补图的最大独立集可以由匈牙利算法求的,所以该题的最大团问题可以转化成补图的最大独立集来做。代码:View Code 1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h&g 阅读全文
posted @ 2012-08-09 09:51 pushing my way 阅读(642) 评论(0) 推荐(0) 编辑
摘要: 独立集:图G中任意两个顶点都不相连的顶点集合。最大独立集:独立集中顶点个数最多。例如二分图:此二分图的最大独立集为6-3=3。比如{1,2,3}或{4,5,6}。而{1,2}也是独立集但是不是最大独立集。二分图的最大独立集=定点数-二分图最大匹配因此可以通过匈牙利算法求得。 阅读全文
posted @ 2012-08-08 15:43 pushing my way 阅读(638) 评论(0) 推荐(0) 编辑
摘要: 问题描述:团就是最大完全子图。给定无向图G=(V,E)。如果UV,且对任意u,vU 有(u,v)E,则称U 是G 的完全子图。G 的完全子图U是G的团当且仅当U不包含在G 的更大的完全子图中,即U就是最大完全子图。G 的最大团是指G中所含顶点数最多的团。例如: (a) (b) (c) (d)图a是一个无向图,图b、c、d都是图a的团,且都是最大团。求最大团的思路:首先设最大团为一个空团,往其中加入一个顶点,然后依次考虑每个顶点,查看该顶点加入团之后仍然构成一个团,如果可以,考虑将该顶点加入团或者舍弃两种情况,如果不行,直接舍弃,然后递归判断下一顶点。对于无连接或者直接舍弃两种情况,在递归前.. 阅读全文
posted @ 2012-08-08 12:07 pushing my way 阅读(29786) 评论(1) 推荐(3) 编辑
摘要: c(n,k)(k<=n)的奇偶性取决于(n-k)与k的二进制表达式是否存在同一位上的两个数码均为1,若存在,则为偶数,反之为奇数。求c(n,k)可以通过公式C(n, 0) = C(n, n) = 1 for all n > 0;C(n, k) = C(n − 1, k − 1) + C(n − 1, k) for all 0 < k < n.递归并保存值,这里用一个二维数组array[n][k],但是考虑到有的题n比较大,数组存不下。还可以通过代码:View Code 1 View Code 2 1 #include <iostream> 3 2 #incl 阅读全文
posted @ 2012-08-08 07:41 pushing my way 阅读(205) 评论(0) 推荐(0) 编辑
摘要: 在算法篇介绍过求这样的某一个范围内第k大的数的三种方法。分治方法,对于求一组范围内的值可以考虑。但是求多组的时候就不行了,因为这种方法会改变原数组的排序。如果要有多组询问时,就必须赋值到另外一个数组中,结果TLE.代码:View Code 1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxnum=100005; 8 int array[maxn 阅读全文
posted @ 2012-08-07 17:32 pushing my way 阅读(263) 评论(0) 推荐(0) 编辑
摘要: 1.划分树是一种基于线段树的数据结构。主要用于快速求出(在log(n)的时间复杂度内)序列区间的第k大值.2.查找整序列的第k大值方法:a.采用快速查找法,分治思想。然而此方法会破坏原序列,并且需要O(n)的时间复杂度。b.使用二叉平衡树进行维护,此方法每次查找时间复杂度仅为O(logn)。然而此方法丢失了原序列的顺序信息,无法查找出某区间内的第k大值c.划分树:基本思想就是对于某个区间,把它划分成两个子区间,左边区间的数小于右边区间的数。查找的时候通过记录进入左子树的数的个数,确定下一个查找区间,最后范围缩小到1,就找到了。3.建树:使用一个辅助数组对原数组进行排序,找到这个区间的中位数a[ 阅读全文
posted @ 2012-08-07 10:57 pushing my way 阅读(226) 评论(0) 推荐(0) 编辑
摘要: 题意:这个题首先给出一个01序列,这个序列的意思是,从一个树的根开始遍历,遇到0走到一个孩子,遇到1则当前节点返回到它的父亲节点,最后回到树的根。求对这样两个01序列进行遍历后形成的两颗树是否同构。分析:1.这个序列中的0和1个数必须相同,否则无法回到根。有几个0就有几个节点。2.遍历01序列建树,记录每个节点的深度和孩子个数,然后排序进行比较。3.一开始,我记录每个节点的孩子个数仅限于孩子(没有记录孙子,曾孙等),结果WA了。应该记录每个节点的所有后代的个数。4.这道题我用的是静态链表。代码:View Code 1 #include <iostream> 2 #include & 阅读全文
posted @ 2012-08-06 08:51 pushing my way 阅读(526) 评论(0) 推荐(0) 编辑