算法模板
算法与数据结构笔记
不维护了
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
c++实现判断一个整数是否为素数
bool is_prime(int n){ for(int i=2;i*i<=n;i++){ if(n%i==0) return false; } return n!=1; }原创 2020-08-19 16:08:00 · 2590 阅读 · 0 评论 -
最小生成树两种解法
文章目录PrimKruskal总结 Prim 运用了贪心的算法。是从某个顶点开始不断添加边的算法。 int cost[MAX_V][MAX_V];//存边权 int mincost[MAX_V];//从集合X出发的边到每个顶点的最小权值 int book[MAX_V]; int V; int prim(){ for(int i=0;i<V;i++){ mincost[i]=INF; book[i]=0; } mincost[0]=0; int res=0; while(1){原创 2020-07-31 22:26:36 · 959 阅读 · 0 评论 -
有向无环图从s出发到t的简单路径条数
文章目录DFS拓扑排序+DP DFS #include <iostream> #include <vector> using namespace std; const int MAX_V = 101; vector<int> map[MAX_V]; int book[MAX_V]; int st, ed; int ans = 0; void dfs(int s) { if (s == ed) { ans++; return;原创 2020-07-30 11:30:48 · 973 阅读 · 0 评论 -
有向无环图的拓扑排序实现
思路:从入度为0的点开始寻找,找到以后放入ans,去掉与该点相邻的所有边。继续寻找第二个入度为0的点,依次类推。 #include <cstring> #include <iostream> #include <queue> #include <vector> using namespace std; const int MAX_V = 101; int V, m; vector<int> map[MAX_V]; int deg[MAX_V]; q原创 2020-06-13 21:37:56 · 385 阅读 · 0 评论 -
输出图中所有负环上的点
#include <cstring> #include <iostream> #include <queue> #include <vector> using namespace std; const int INF = 0x3f3f3f3f; const int MAX_V = 100 + 1; int V, m; typedef pair<int, int> P; struct edge { int to, cost; edg原创 2020-06-13 19:43:39 · 935 阅读 · 0 评论 -
用dijkstra求次短路附例题
思路: 在原来的d数组上增加d2数组保存次短路。 求从s到t的次短路径有两种情况: 1、起点s到某个顶点u的最短路+d(u,t)。 2、起点到某个顶点u的次短路+d(u,t)。 修改后的dijkstra: void dijkstra(int st) { fill(d1, d1 + n + 1, INF); fill(d2, d2 + n + 1, INF); priority_queue<P> q; d1[st] = d2[st] = 0; q.push(原创 2020-06-08 11:52:23 · 691 阅读 · 0 评论 -
最短路问题四种解法
文章目录DijkstraSPFAfloyd多源最短路 Dijkstra 用于解决带权图的单源最短路问题。要求不能出现负权边。原因是只要没有负权边,则d[i]就不会在之后的更新中变小。 思路:从起点开始,每次都找到距离当前点最近的点,更新d[]数组。 typedef pair<int,int> P; struct edge{int to,cost;}; int V;//顶点数; vector<edge> map[MAX_V]; int d[MAX_V]; void dijkstra(原创 2020-06-03 10:46:32 · 1139 阅读 · 0 评论 -
两种方法求树的直径(BFS/DFS)
树的直径:树上距离最远的两个点的距离。 方法: 随机选择一个节点,假设是1,在以1为根的有根树上进行一遍dfs或者bfs遍历,并记录下每个点到根的距离。 选择到根距离最远的点u(如果有多个,随机选择一个都可以),根据节点u再建立一个有根树,这个时候以u为根的有根树上进行一遍dfs或者bfs遍历,并记录下每个点到根的距离。 第二次遍历之后,距离最远的点对应的距离就是树的直径。 代码: #include <cstring> #include <iostream> #include <原创 2020-05-27 10:38:47 · 1344 阅读 · 0 评论 -
n叉树的遍历递归实现
文章目录性质遍历前序遍历后序遍历层序遍历(BFS) 如果一个无向连通图中不存在回路,则称这个图为树。 性质 若树上结点数为n,则边数一定为n-1。 树上任意一对结点之间有且只有一条路径。 由于树是稀疏图,常使用邻接表存储。 遍历 假设信息已经存储在vector<int> node里了。 前序遍历 void preorder(int n){ cout<<n<<" "; for(auto i:node[n]){ preorder(i); } } 后序遍历 vo原创 2020-05-27 10:22:57 · 529 阅读 · 0 评论 -
求二叉树结点的高度和深度
不存在的结点用-1表示。 #include <iostream> using namespace std; struct node { int p, l, r; }; node N[100]; int d[100], h[100]; void depth(int u, int m) { if (u == -1) return; d[u] = m; depth(N[u].l, m + 1); depth(N[u].r, m + 1); }原创 2020-05-25 16:53:56 · 857 阅读 · 0 评论 -
DFS和并查集判断图是否联通
使用邻接表存图。 若图 #include <iostream> #include <vector> using namespace std; int book[1000000]; vector<int> node[1000000]; void dfs(int u) { book[u] = 1; for (auto i : node[u]) { if (!book[i]) { dfs(i); }原创 2020-05-25 16:25:11 · 465 阅读 · 0 评论 -
二叉树的前中后序遍历模板
#include <iostream> using namespace std; struct node { int p, l, r; }; node N[100]; void preorder(int u) { if (u == -1) return; cout << u << " "; preorder(N[u].l); preorder(N[u].r); } void inorder(int u) {原创 2020-05-25 16:07:23 · 273 阅读 · 0 评论 -
DFS求有向图是否存在环
思路: 利用book[]标记状态,0表示未访问,1表示正在访问,2表示所有子节点访问完毕。然后dfs每个点寻找是否存在回路。 #include <iostream> #include <vector> using namespace std; vector<int> map[1111]; int flag = 0, book[1111]; bool dfs(int cur) { book[cur] = 1; for (auto i : map[cur])原创 2020-05-21 22:03:03 · 676 阅读 · 0 评论 -
图的欧拉回路/欧拉路径判断
欧拉回路/路径判断方法: 首先图必须是联通的,用并查集判即可 无向图欧拉回路:所有点度数都为偶数 无向图欧拉路径:图中只有两个点(或0个点)度数为奇数 有向图欧拉回路:所有点入度=出度 有向图欧拉路径:一个点入度=出度+1,一个点出度=入度+1(两个端点),其余点(或所有点)入度=出度 无向图 判断是否存在欧拉路径/回路: 利用并查集判断是否联通,利用degree数组统计结点数。 #include <iostream> using namespace原创 2020-05-21 21:19:35 · 3247 阅读 · 0 评论 -
并查集模板及其优化
int f[10000]; //非递归 int getf(int a) { int root = a; while (f[root] != root) root = f[root] int tmp; while (a != root) { tmp = f[a]; f[a] = root; a = tmp; } return root; } //递归 int getf(int a){ if(f原创 2020-05-19 23:08:28 · 320 阅读 · 0 评论 -
图的多种表示与遍历方法
文章目录邻接矩阵DFSBFS邻接表DFSBFS 邻接矩阵 用二维矩阵map表示图。 int n,m, a, b; int main(){ cin >> n >> m; //初始化二维矩阵 for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++){ if (i == j)map[i][j] = 0; else map[i][j] = 0xfff; } //读入边 for (int i原创 2020-05-17 12:12:54 · 364 阅读 · 0 评论 -
快速幂模板及其原理
以7的10次方为例,将10写成二进制的形式,也就是1010 。 现在我们要计算7101027^{1010_2}710102,可以怎么做?我们很自然地想到可以把它拆分。 实际上,对于任意的整数,我们都可以把它拆成若干个7100..27^{100.._2}7100..2的形式相乘。而这些恰好就是 717^171 、727^272、747^474……我们只需不断把底数平方就可以算出它们。 //非递归快速幂 int qpow(int a, int n){ int ans = 1; while(n原创 2020-07-30 20:51:39 · 234 阅读 · 0 评论 -
RMQ求区间最值与其对应下标
注意:数组下标从1开始。 int dp[1000001][40]; int pos[1000001][40]; void ST(int n) { fill(dp[0], dp[0] + 1000001 * 20 + 1, 1111111); for (int i = 1; i <= n; i++) { dp[i][0] = a[i]; pos[i][0] = i; } for (int j = 1; (1 << j) <原创 2020-07-28 22:19:11 · 234 阅读 · 0 评论 -
状态压缩动态规划例题
文章目录前言消除字符串 前言 当元素数量较小(不超过20)时,想要存储每个元素取或不取,可以借助位运算压缩状态。空间复杂度为O(2n)O(2^n)O(2n)。 消除字符串 蒜头君喜欢中心对称的字符串,即回文字符串。现在蒜头君手里有一个字符串 SS,蒜头君每次都会进行这样的操作:从 SS 中挑选一个回文的子序列,将其从字符串 SS 中去除,剩下的字符重组成新的字符串 SS。 蒜头君想知道,最少可以进行多少次操作,可以消除整个字符串。 输入格式 输入一行。输入一个字符串 SS(1≤length(S)≤16),字原创 2020-05-18 00:07:04 · 353 阅读 · 0 评论 -
快速理解动态规划入门例题
文章目录可行路径数目墙壁涂色 可行路径数目 Problem Description 棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘用坐标表示,A点(0,0)、B点(n,m)(n,m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。 Input 一行四个数据,用空格原创 2020-05-17 23:46:13 · 328 阅读 · 0 评论 -
快速上手BFS入门例题
文章目录最短路径回家走迷宫最少步数总结 最短路径 回家 蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家。花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方。” 蒜头君希望能尽快回到家中,他需要首先取得任意一把钥匙,请你帮他计算出回家所需要的最短路程。 蒜头君生活的城市可以看做是一个n×m的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右 44 个方向移动,移动一个格子算做走一步。 输入格式 第一行有两个整数原创 2020-05-14 17:50:30 · 564 阅读 · 0 评论 -
DFS入门例题
文章目录走迷宫 走迷宫 给一个n行m列的2维的迷宫,‘S’表示迷宫额起点,‘T’表示迷宫的终点,’#‘表示不能通过的点,’.’ 表示可以通过的点。你需要从’S’出发走到’T’,每次只能上下左右走动,并且只能进入能通过的点,每个点只能通过一次。现在要求你求出有多少种通过迷宫的的方案。 输入格式 第一行输入n,m (1≤n,m≤10)表示迷宫大小。 接下来输入n行字符串表示迷宫。 输出格式 输入通过迷宫的方法数。 样例输入1 2 3 S.# …T 样例输出1 2 样例输入2 3 3 S… .#. …T 样例输出原创 2020-05-14 17:20:18 · 707 阅读 · 0 评论 -
高精度运算模板(非负整数)
加法 #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int L=1000; string add(string a,string b){ string ans; int na[L]={0},nb[L]={0}; int la=a.siz...原创 2020-04-29 12:42:33 · 165 阅读 · 0 评论 -
数据离散化C++模板
复杂度O(nlog(n))O(nlog(n))O(nlog(n)): //vector+sort+unique+lower_bound #include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; int n,a[maxn]; vector <int> key; int main(){ cin &...原创 2020-04-28 23:02:35 · 452 阅读 · 0 评论 -
归并排序求逆序对
题目 输入一串数a1,…,an,逆序对定义为满足以下两个条件的元组(i,j): 1≤i<j≤n1≤i<j≤n1≤i<j≤n ai>ajai>ajai>aj 求逆序对个数。 输入格式 第一行一个数n,第二行总共n个数,n个数可能有重复数。 其中n≤105,ai≤109。 输出格式 一个数表示逆序对个数。 思路: 归并排序合并的过程就是找出逆序对的过程,因此可以在归...原创 2020-04-28 17:43:53 · 288 阅读 · 0 评论
分享