- 博客(16)
- 收藏
- 关注
原创 单源最短路的建图方式
题目1:热浪 分析: 由题目可知,求的是两个点之间的最短距离,边权为正数且点数和边数属于同一量级,使用堆优化版的dijkstra进行求解即可。 这道题是无向图,我们建有向图能求解吗? 不能。 因为如果a 和 b有一条边, 我们只建一条有向边, 意味着 a能到b, b确不能到a, 如果输入时起点是b,终点是a,那么我们就到达不了a,答案出错。 关于能否只建有向图求解无向图的问题, 一定要证明,如果证明不出来,直接按题目要求建立无向图。 时间复杂度:O(m∗logm)O(m * log ^m)O(m∗logm)
2022-05-31 10:03:28
188
原创 二分图的两个常用算法
染色法判断是否是二分图 题目1: 染色法判定二分图 时间复杂度:O(n+m)O(n + m)O(n+m) 代码区: #include<iostream> #include<cstring> using namespace std; const int N = 1e5 + 10, M = 2e5 + 10; int n, m; int h[N], e[M], ne[M], idx; int color[N]; void add(int a, int b) { e[idx
2022-05-29 09:48:59
144
原创 最小生成树
最小生成树的图中允许存在负环 prim 思路: 时间复杂度:O(n2+m), n 表示点数,m 表示边数 模版: int n; // n表示点数 int g[N][N]; // 邻接矩阵,存储所有边 int dist[N]; // 存储其他点到当前最小生成树的距离 bool st[N]; // 存储每个点是否已经在生成树中 // 如果图不连通,则返回INF(值是0x3f3f3f3f), 否则返回最小生成树的树边权重之和 int prim() {
2022-05-28 18:00:28
180
原创 最短路常用算法
最短路的专有名词: 源点: 表示起点 汇点: 表示终点 稀疏图: 点数和边数在同一个量级 稠密图: 边数和点数的平方在同一个量级 注意: 求最短路的要求的是该图不能含有负环, 如果图中有负环, 那么我们可以一直在这个负环中走无穷多次, 那么我们的最短路的值就会变成负无穷。 单源最短路和多源最短路有什么区别? 单源最短路: 求的是固定的一个起点, 到它所有能到的点之间的距离。 多源最短路: 求的是起点不固定, 即任意两个点之间的距离 普素版dijkstra 思路: 模版: int g[N][N]; /
2022-05-28 16:35:10
269
原创 拓扑排序算法
算法一:拓扑排序: 模版: 时间复杂度: O(n+m), n 表示点数,m 表示边数 bool topsort() { int hh = 0, tt = -1; // d[i] 存储点i的入度 for (int i = 1; i <= n; i ++ ) if (!d[i]) q[ ++ tt] = i; while (hh <= tt) { int t = q[hh ++ ];
2022-05-28 10:27:23
138
原创 dfs之连通性模型
题目1: 迷宫 分析: 这题考查的就是dfs的一个简单的应用。只是判断题目是否存在解,用dfs最好,找到一组解就退出。 这道题dfs过程中为什么不要恢复现场的? 这个主要是和递归搜索树有关, 时间复杂度: 代码区: #include<iostream> #include<cstring> using namespace std; const int N = 110; int n; int x1, y1, x2, y2; char g[N][N]; bool st[N][N];
2022-05-23 11:03:02
249
原创 最短路模型
为什么能用bfs求解? bfs适用于求解权值为定值的最短路问题。 bfs是先把一个点加入队列,然后将它能够直接到达的点再加入到队列。整个队列中的元素距离起点的举例是非严格单调递增的。所以我们第一次拓展到该点的时候,起点到这个点的距离就是最小距离。 能用dfs求解这个问题吗? 可以,但是需要注意的是,dfs执行放入时候是一条路走到黑,也就是说你并不知道单前点到起点的距离是不是最优的,需要dfs完整张图才能够的到最优解。 题目1: 迷宫问题 分析: 这道题求的是左上角到右下角的最短路,没有规定每条边的权值,我们
2022-05-22 15:33:15
183
原创 bfs常见的几种题
bfs算法 技巧: 在做 bfs/dfs 问题时我们通常可能会用到 偏移量 这个技巧 floodfill(洪水覆盖算法) 题目1:池塘计数 分析: bfs是枚举到一个格子时, 把它所有能拓展到的位置都加入到队列中 dfs是枚举到一个格子时,如果它能拓展到另一个格子, 那么它直接去拓展另一个格子。 一般而言同样的一道题如果用dfs代码和bfs代码都能实现, 用dfs实现会更加简单。因为它不需要额外维护一个队列 时间复杂度:O(n∗m)O(n * m)O(n∗m) 代码区:(bfs实现) #include&l
2022-05-22 10:24:32
455
原创 区间dp模版
区间dp 题目1: 环形石子合并 分析: 时间复杂度: O(n3)O(n^3)O(n3), 1秒之内可以出解 代码区: #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N = 310; int n; int w[N]; int s[N]; int f[N][N]; int main() { cin >> n;
2022-05-17 23:09:42
278
原创 常见的树形dp
树形dp 一般通过递归来完成这类问题,通过递归算出小的子树, 一般是用树的后续遍历。 一般而言有两类: f[u][0/ 1], 以u为根, u这个节点选还是不选 f[u][v], 有依赖的背包问题, 枚举体积有两种方式,按体积为1为增量开始递增。或者使用二进制的方式来枚举体积。这两种方法的时间复杂度不同。具体问题具体分析,保证不能超时。 题目1:没有上司的舞会 分析: 时间复杂度: O(n)O(n)O(n), 量级1e3, 1秒之内可以出解 代码区: #include<iostream> #
2022-05-17 23:09:00
146
原创 状态压缩dp
状态压缩dp 题目1: 蒙德里安的梦想 分析: 这个同学的题解写的真的不错:题解 时间复杂度: 代码区: #include<iostream> #include<cstring> #include<vector> using namespace std; const int N = 12, M = 1 << 11; int n, m; bool st[M]; vector<int> state[M]; long long f[N][M];
2022-05-15 19:45:37
168
原创 状态机模型
状态机dp 对dp问题认识: 其实dp问题是在一个有向无环图上递推的过程, 在dag上递推求得答案。 图论问题我们需要建图, 但是dp问题我们不需要真的把图建出来,其实 状态表示,f(i, j)表示的是图中的一个节点, f(i, j)存的值是从起点到该点的值(最大值、最小值、方案数)。状态转移方程其实描述的就是当前点可以由前面已经求得的哪些点转移过来,实际上就是描述的是当前点可以由前面的哪些点到达, 用状态转移方程递推求得答案。 为什要引入状态机: 在背包问题中, 前面一个物品的选择是不会影响后一个物品,
2022-05-14 20:48:22
471
原创 背包特训集
背包集训 题目1: 采药 分析: 01背包裸题, 直接写 时间复杂度: O(n∗m)O(n * m)O(n∗m) 量级:1e5, 1秒之内可以出解 代码区: #include<iostream> #include<cstring> using namespace std; const int N = 1010; int n, m; int f[N]; int main() { cin >> m >> n; for(int
2022-05-13 20:12:06
128
原创 背包模型
第二个模型:背包模型 背包问题的种类: 01背包:每个物品的个数只有一个, 每个物品最多可以选1个 完全背包: 每个物品的个数有无限个, 不超过背包容积的情况下, 每个物品可选无数个 多重背包: 每个物品的个数有有限个, 不能超过背包容积, 不能超过该物品给定的个数 分组背包: 每组物品只能选一个, 每组物品最多只能选一个 01背包: 题目1 链接:01背包问题 dp数组的初始化: 这里的选择是每个物品选或者不选, 所有的物品都可以都可以通过这个表达式推导出来,因为要求的是最大值, 所以最小值初始化
2022-05-09 16:16:14
304
原创 数字三角形
文字 文字 文字 文字 大概吧 标题 标题 vector<int> twoSum(vector<int>& nums, int target) { vector<int> res; unordered_map<int, int> hash; for(int i = 0; i < nums.size(); i ++) { int another =
2022-05-08 23:27:54
546
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅