算法模板
算法与数据结构笔记
不维护了
这个作者很懒,什么都没留下…
展开
-
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 · 2471 阅读 · 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 · 718 阅读 · 0 评论 -
有向无环图从s出发到t的简单路径条数
文章目录DFS拓扑排序+DPDFS#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 · 738 阅读 · 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 · 250 阅读 · 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 · 716 阅读 · 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 · 466 阅读 · 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 · 977 阅读 · 0 评论 -
两种方法求树的直径(BFS/DFS)
树的直径:树上距离最远的两个点的距离。方法:随机选择一个节点,假设是1,在以1为根的有根树上进行一遍dfs或者bfs遍历,并记录下每个点到根的距离。选择到根距离最远的点u(如果有多个,随机选择一个都可以),根据节点u再建立一个有根树,这个时候以u为根的有根树上进行一遍dfs或者bfs遍历,并记录下每个点到根的距离。第二次遍历之后,距离最远的点对应的距离就是树的直径。代码:#include <cstring>#include <iostream>#include <原创 2020-05-27 10:38:47 · 1029 阅读 · 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 · 412 阅读 · 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 · 745 阅读 · 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 · 360 阅读 · 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 · 195 阅读 · 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 · 491 阅读 · 0 评论 -
图的欧拉回路/欧拉路径判断
欧拉回路/路径判断方法: 首先图必须是联通的,用并查集判即可 无向图欧拉回路:所有点度数都为偶数 无向图欧拉路径:图中只有两个点(或0个点)度数为奇数 有向图欧拉回路:所有点入度=出度 有向图欧拉路径:一个点入度=出度+1,一个点出度=入度+1(两个端点),其余点(或所有点)入度=出度无向图判断是否存在欧拉路径/回路:利用并查集判断是否联通,利用degree数组统计结点数。#include <iostream>using namespace原创 2020-05-21 21:19:35 · 2542 阅读 · 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 · 200 阅读 · 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 · 264 阅读 · 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 · 146 阅读 · 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 · 135 阅读 · 0 评论 -
状态压缩动态规划例题
文章目录前言消除字符串前言当元素数量较小(不超过20)时,想要存储每个元素取或不取,可以借助位运算压缩状态。空间复杂度为O(2n)O(2^n)O(2n)。消除字符串蒜头君喜欢中心对称的字符串,即回文字符串。现在蒜头君手里有一个字符串 SS,蒜头君每次都会进行这样的操作:从 SS 中挑选一个回文的子序列,将其从字符串 SS 中去除,剩下的字符重组成新的字符串 SS。蒜头君想知道,最少可以进行多少次操作,可以消除整个字符串。输入格式输入一行。输入一个字符串 SS(1≤length(S)≤16),字原创 2020-05-18 00:07:04 · 235 阅读 · 0 评论 -
快速理解动态规划入门例题
文章目录可行路径数目墙壁涂色可行路径数目Problem Description棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。棋盘用坐标表示,A点(0,0)、B点(n,m)(n,m为不超过15的整数),同样马的位置坐标是需要给出的。现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。Input一行四个数据,用空格原创 2020-05-17 23:46:13 · 213 阅读 · 0 评论 -
快速上手BFS入门例题
文章目录最短路径回家走迷宫最少步数总结最短路径回家蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家。花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方。”蒜头君希望能尽快回到家中,他需要首先取得任意一把钥匙,请你帮他计算出回家所需要的最短路程。蒜头君生活的城市可以看做是一个n×m的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右 44 个方向移动,移动一个格子算做走一步。输入格式第一行有两个整数原创 2020-05-14 17:50:30 · 461 阅读 · 0 评论 -
DFS入门例题
文章目录走迷宫走迷宫给一个n行m列的2维的迷宫,‘S’表示迷宫额起点,‘T’表示迷宫的终点,’#‘表示不能通过的点,’.’ 表示可以通过的点。你需要从’S’出发走到’T’,每次只能上下左右走动,并且只能进入能通过的点,每个点只能通过一次。现在要求你求出有多少种通过迷宫的的方案。输入格式第一行输入n,m (1≤n,m≤10)表示迷宫大小。接下来输入n行字符串表示迷宫。输出格式输入通过迷宫的方法数。样例输入12 3S.#…T样例输出12样例输入23 3S….#.…T样例输出原创 2020-05-14 17:20:18 · 565 阅读 · 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 · 100 阅读 · 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 · 317 阅读 · 0 评论 -
归并排序求逆序对
题目输入一串数a1,…,an,逆序对定义为满足以下两个条件的元组(i,j):1≤i<j≤n1≤i<j≤n1≤i<j≤nai>ajai>ajai>aj求逆序对个数。输入格式第一行一个数n,第二行总共n个数,n个数可能有重复数。其中n≤105,ai≤109。输出格式一个数表示逆序对个数。思路:归并排序合并的过程就是找出逆序对的过程,因此可以在归...原创 2020-04-28 17:43:53 · 174 阅读 · 0 评论