
经典算法
NameiCc
己不由心,身又岂能由己
展开
-
拓扑排序
拓扑排序就是根据给出的集合上的偏序关系得到该集合上的一个全序。进行拓扑排序可以根据入度求出:不断地选择入度为0的结点,并且删除该结点以及以该结点为起点的弧。如果在过程中所有的结点入度均大于0,则证明无法进行拓扑排序。int n; //结点数int m; //偏序数void TopoSort(){ memset(G,0,sizeof(G)); memset(in,0,siz原创 2015-06-16 13:23:12 · 377 阅读 · 0 评论 -
0-1背包问题
有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下尽量大。 思想:f(i,j)表示把前i个物品装到容量为j的背包中的最大总重量,则f(i,j)=max{f(i-1,j),f(i-1,j-V[i])+W[i]}。边界为: i=0时为0,j1 for(int i=1; i)2 for(原创 2015-06-09 16:59:22 · 295 阅读 · 0 评论 -
最短路
单源最短路问题就是求出图中源点到所有结点的最小距离。Dijkstra算法每次找出距离源点最近的点,然后更新举例。 int n; //顶点数int m; //边数void init(){ int u,v,w; for(int i=1; i<=n; i++) for(int j=i; j<=n; j++) G[i][j] =原创 2015-06-16 19:08:54 · 302 阅读 · 0 评论 -
并查集
并查集用于把一些不相交的集合进行合并,查询两个元素是否属于同一集合等。并查集初始化,是将单个元素华为单独的集合。查,是查找元素所在的集合(根节点)。并,是将两个元素所在的集合合并为一个集合。/*初始化*/void init(){ for(int i=0; i<maxn; i++) fa[i] = i;}/*查找所在集合*/int find_set(int x原创 2015-06-14 13:41:29 · 302 阅读 · 0 评论 -
fibonacci数列矩阵快速幂
对于矩阵 [ 1 1 1 0 ] 的n次幂,第一行第二个元素(右上角)的元素即为fibonacci数列的第n项,由此可以根据矩阵的乘法计算fibonacci数列的元素值 矩阵的快速幂利用的也是幂乘的二分法,只不是换成了矩阵的乘法,可用以函数处理。 /*可以定义一个二维数组的结构体*/typedef struct matrix{原创 2015-06-14 11:05:34 · 965 阅读 · 0 评论 -
N皇后问题
在N*N棋盘上放置着N个皇后,使得她们不能相互攻击,每个皇后的攻击范围是同行同列和同对角线,求出所有解。 皇后不能同行,因此可以逐行考虑每个皇后,使其纵向和斜向不会攻击即可。 /*打印棋盘*/void print(){ for(int i=0; i<n; i++) { int c = C[i]; for(int原创 2015-06-14 13:16:34 · 458 阅读 · 0 评论 -
欧拉回路
对于给定的图G,如果从某个结点出发走一条道路,使得它恰好通过G的每一条边恰好一次,该路径成为欧拉道路。如果该路径起点终点相同,那么成为欧拉回路(可见,欧拉回路是特殊的欧拉道路)。这也是一笔画问题。不同的图,欧拉道路和回路的判断条件也不同,当然图都必须是连通图。如果是有向图,存在欧拉道路的条件是没有或者只有两个入度不等于出度的点,并且必须是一个点的出度比入度大一(欧拉道路的起点),一个点的入度比原创 2015-06-19 17:44:11 · 519 阅读 · 0 评论 -
最小生成树
最小生成树是含有n个结点的连通图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。求解最小生成树可以用Prim或者Kruskal算法。int n; //顶点数int m; //边数/*Prim算法*/int vis[maxn];int pre[maxn];int dist[maxn];int G[maxn][maxn];void Prim(){原创 2015-06-14 15:31:29 · 314 阅读 · 0 评论 -
树状数组
下面是我自己对树状数组的认识。。。树状数组,是一个查询和修改复杂度都为log(n)的数据结构。树状数组支持区间查询,单值修改。树状数组之所以查询快速,是因为相当于对数组有效的划分和维护。这图是盗的度娘的。。。C数组就是树状数组。C[1]=A[1];C[2]=A[1]+A[2];C[3]=A[3];C[4]=A[1]+A[2]+A[3]+A[4];C[5]=A[5];原创 2015-06-18 14:41:48 · 550 阅读 · 0 评论 -
判断一个整数中有多少个1(二进制)--LeetCode 191
整数分为有符号整数以及无符号整数。 对于无符号整数,将整数和1相与,然后将整数右移一位,直到整数为0即可。对于有符号整数,逻辑移位左右移位都是舍弃和补0。算术移位左移舍弃补0,但是右移需要保证符号位不变。因而正整数右移舍弃补0,负整数就要补1,在这种情况下如果采用算术移位,最高位永远都是1,会陷入死循环。在该题中,算术移位会死循环,逻辑移位才能得到正确结果。看了一下测试数据,有出现原创 2016-03-03 19:44:48 · 932 阅读 · 0 评论