TP

  • 二分图的概念:
  • 二分图常用算法:
    • 染色法(判断一个图是否为二分图):
    • 匈牙利算法(求出二分图的最大匹配数):
  • 相应题目应用:
    • 二分图 染色 应用:
      • Acwing:关押罪犯
    • 二分图最大匹配应用:
      • Acwing:棋盘覆盖
      • 洛谷:矩阵游戏
    • 二分图最大匹配的一些推论:
    • 二分图最小点覆盖应用:
      • Acwing:机械任务
      • Acwing:泥地
    • 二分图最大独立集应用:
      • Acwing:骑士放置
    • 二分图 最大路径点覆盖 与 最大路径重复点覆盖 应用:
      • Acwing:捉迷藏

二分图的概念:

二分图通常针对 无向图 问题(有些题目虽然是有向图,但一样有二分图性质)

在一张图中,如果能够把全部的点分到 两个集合 中,保证两个集合内部没有 任何边 ,图中的边 只存在于两个集合之间,这张图就是二分图
——————————————————————————————————————————

二分图常用算法:

染色法(判断一个图是否为二分图):

算法原理就是,用 黑 与 白 这两种颜色对图中点染色(相当于给点归属一个集合),一个点显然不能同时具有两种颜色,若有,此图就不是二分图



代码:

bool dfs(int u, int c) {color[u] = c;//当前点先染色for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];//对于这个点连接的所有的点if (color[j]) {//如果已经被染过色了if (color[j] == c)return false;//就需要判断一下,如果两点颜色一样,染色就冲突了}else if (!dfs(j, 3 - c))return false;//否则dfs去染下一个结点,赋予的颜色肯定要跟 c 不一样//3 - 1 == 2,3 - 2 == 1//同时传回染色成功与否的信息}return true;
}bool check() {memset(color, 0, sizeof color);//0 —— 未染色,1 —— 黑色,2 —— 白色for (int i = 1; i <= n; i++)if (color[i] == 0)//一旦某个点没染过色,dfs去染色if (!dfs(i, 1))return false;//如果传回false显然失败,此图不是二分图return true;//否则true
}

遍历了这张图的点和边,时间复杂度O(n+m)O(n + m)O(n+m)

——————————————————————————————————————————

匈牙利算法(求出二分图的最大匹配数):

满足 是二分图 这个前提,才能使用匈牙利算法

所谓 最大匹配数 的意思就是:

两个集合分别选一个点,这两个点之间有边就确认一段关系(一个集合中的两点 占有 另一集合中同一个点 是不合法的 一夫一妻(确信) ),最多的关系数量就是这张二分图的最大匹配

代码:

bool find(int x) { //标准匈牙利for (int j = 1; j <= n; j++)if (!st[j] && g[x][j]) { //x 点连向的所有点(因为是二分图,所以这些点都在右集合),如果存在边且没标记过st[j] = true;//标记一下,防止多次遍历int t = match[j];//右集合中该点的匹配对象if (!t || find(t)) { //没对象就可以和 x 匹配,有的话就让 t 尝试更改对象,能更改就和 x 匹配,不能就falsematch[j] = x;return true;}}return false;
}int main() {cin >> n;int ans = 0;for (int i = 1; i <= n; i++) { //遍历左集合memset(st, 0, sizeof st);//每次都要重置标记if (find(i))ans++;//一旦有一个匹配,数量就++}cout << ans;return 0;
}

最坏情况会每个点遍历全部边一次,所以时间复杂度是O(nm)O(nm)O(nm)

但匈牙利算法还是很优秀的,大部分情况时间都比较小

如果想要更优秀的算法左转 网络流 吧,匈牙利匹配本质上还是网络流的一种特殊形式,网络流可以更好地解决此类问题。网络流真是太简单了bushi

——————————————————————————————————————————

相应题目应用:

二分图 染色 应用:

Acwing:关押罪犯


题意又臭又长,总结就是:

尽可能将 仇恨值大的 两名罪犯放在不同监狱中

把仇恨值当作罪犯之间的边的边权,两座监狱看作两个集合

这道题就变成了 如何让二分图 两集合之间的边权 尽可能大(使得集合内部边权尽可能小,冲突也就没那么激烈)

观察数据范围,此题可以用 二分 + 染色法 求解

代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 20010, M = 200010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
int h[N], e[M], ne[M], w[M], idx;
int color[N];//染色,记录该点的状态:0 —— 未染色、1 —— 染白、2 —— 染黑void add(int a, int b, int x) {e[idx] = b, w[idx] = x, ne[idx] = h[a], h[a] = idx++;
}bool dfs(int u, int c, int mid) {color[u] = c;//染该点for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (w[i] <= mid)continue;//mid是答案,是设定的集合内部最大边权,如果该边小于等mid,边两点显然可以随意处理,放在一个集合内也行//否则,该边两点就严格要放在两个不同集合,防止冲突if (color[j]) { //连向的点若被染过色if (color[j] == c)return false;//显然色不能相同}else if (!dfs(j, 3 - c, mid))return false;//没被染过就染该点}return true;//成功
}bool check(int mid) {mem(color, 0);//每次重新对点染色for (int i = 1; i <= n; i++)if (color[i] == 0)//枚举每一个点是因为有可能有多个连通块if (!dfs(i, 1, mid))return false;//要保证都为二分图return true;
}int main() {cinios;cin >> n >> m;mem(h, -1);for (int i = 0; i < m; i++) {int a, b, x;cin >> a >> b >> x;add(a, b, x);//二分图通常针对的都是无向图add(b, a, x);}int l = 0, r = 1e9;//二分答案while (l < r){int mid = l + r >> 1;//mid 即是最小的最大影响力//比 mid 小的影响显然都可以随意塞到监狱中//比 mid 大的影响要让其尽可能不存在(即一边两点分别在图的两个不同子集中)//也就是询问能否用比 mid 大的边建立一个二分图if (check(mid))r = mid;//能的话显然包含答案else l = mid + 1;//不能就要增大,右移往答案靠拢}cout << l;return 0;
}

——————————————————————————————————————————

二分图最大匹配应用:

Acwing:棋盘覆盖


看上去像状压dp,但一看数据范围21002^{100}2100状压肯定炸,所以探讨一下是否具有二分图的性质

如果把每个格子看成点,放置骨牌(长2宽1)的操作可以看成 两点之间连一条边

那每个格子能放置骨牌就有四种情况四个方向连四条边(除非另一个格子被禁止放置)

每个格子都这样处理,可以得到一张图

可以发现的是,能放置最多骨牌 == 能不重复尽可能多地选取边 == 最大匹配数量

之前说过,求最大匹配的前提是这张图是二分图,所以我们需要判断下这张图是否具有二分图的性质

纸上作画一下便可发现,奇数格/偶数格 彼此之间是没有边的(相当于二分图中的两个集合)

因此,
代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 110, M = 50010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
bool g[N][N], st[N][N];
PII match[N][N];
int dx[] = { -1,0,1,0 }, dy[] = { 0,1,0,-1 };//防止长2宽1的骨牌,可以看作是在相邻两格之间建边(要求合法)
//结果要求最多能放多少块骨牌,就相当于 “ 最多有多少条匹配边 ”
//经过观察象棋棋盘上黑白格的分布,我们可以推导出,N行N列的棋盘具有二分图性质
//至此,该问题就变成了一个二分图最大匹配求解问题int find(int x, int y) { //匈牙利算法for (int i = 0; i < 4; i++) { //每个点的边指向都确定了,所以可以不建边int a = x + dx[i], b = y + dy[i];if (a <= 0 || b <= 0 || a > n || b > n || g[a][b])continue;//越界或者触碰禁止的格子就不处理PII t = match[a][b];if (st[t.fx][t.fy])continue;//防止多次遍历st[t.fx][t.fy] = true;if (t.fx == 0 || find(t.fx, t.fy)) { //一旦该点没被标记过,或者点曾经的对象可以找到下家match[a][b] = { x,y };return true;//该点就能匹配//搜索时是遍历左子集往右子集的边,但match记录的是右子集点的对象}}return false;
}int main() {cinios;cin >> n >> m;while (m--){int a, b;cin >> a >> b;g[a][b] = true;//点数较小,用邻接矩阵存储方便}int ans = 0;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)if (i + j & 1 && !g[i][j]) { //只对集合一半的点处理匹配,同时不能是障碍mem(st, 0);//每次要重置标记if (find(i, j))ans++;//匹配成功++}cout << ans;return 0;
}

同类型题

洛谷:矩阵游戏


洛谷题解就挺好

目的是使得最终(1,1)(2,2)…(n,n)都有一个点

可以看作为,最终状态需要每 i 行和 i 列都存在一个匹配

建图方式:对于 i 行 j 列的1点,建一条 i 连向 j 的边即可,最后跑一个二分图匹配,只有匹配数为 n 才能说明有解

可以证明交换行、交换列的操作不会影响匹配数

代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 210, M = 40010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
int h[N], e[M], ne[M], idx;
int match[N << 1];
bool st[N << 1];void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}bool find(int x) { //标准匈牙利for (int i = h[x]; ~i; i = ne[i]) {int j = e[i];if (st[j])continue;st[j] = true;if (!match[j] || find(match[j])) {match[j] = x;return true;}}return false;
}int main() {cinios;cin >> T;while (T--){cin >> n;mem(h, -1);idx = 0;for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++) {cin >> k;if (k)add(i, n + j);//行对列建边//虽然二分图是无向图问题,但只用建单向边即可,枚举其中一个集合}mem(match, 0);int mat = 0;for (int i = 1; i <= n; i++) {mem(st, 0);if (find(i))mat++;}if (mat == n)cout << "Yes";//匹配数必须为 nelse cout << "No";cout << '\n';}return 0;
}

——————————————————————————————————————————

二分图最大匹配的一些推论:

由最大匹配推导而来,本文不细节探讨证明(我也不会啊 )

——————————————————————————————————————————

二分图最小点覆盖应用:

证明可得:二分图的最大匹配数 == 最小点覆盖(证明理解不能,寄了)

什么是最小点覆盖?

最小点覆盖并不只在二分图中才存在

在一个图中任意选取 最少 多少个点(两个集合中都可以选!),可以保证图中 所有的边都与选取的点相连

这个数量就是最小点覆盖

Acwing:机械任务


代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 110, M = 400010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
int match[N];
bool st[N], g[N][N];//证明可得:二分图的最大匹配数 == 最小点覆盖(证明理解不能,寄了)//什么是最小点覆盖?
//最小点覆盖并不只在二分图中才存在,任意一个图中
//选取 最少 多少个点,可以保证图中 所有的边都与选取的点相连
//这个数量就是最小点覆盖bool find(int x) { //标准匈牙利for (int i = 1; i < m; i++)if (!st[i] && g[x][i]) { //确保有边st[i] = true;int t = match[i];if (t == 0 || find(t)) {match[i] = x;return true;}}return false;
}int main() {cinios;//该题就可以转化成一个最小点覆盖问题,然后用二分图最大匹配求解//对于每一个任务 i,可以选择(A 的 a[i] 模式)或(B 的 b[i] 模式)解决////所以在 a[i] 和 b[i] 之间建一条边,代表任务 i(这样的图显然是二分图)//要完成所有任务显然表示要 选取所有的边// //这个问题就可以转化成:最少标记多少个点,即在 a[i] 与 b[i] 中选择其中一个,可以保证图中所有的边都与选取的点相连while (cin >> n, n){cin >> m >> k;mem(g, 0);mem(match, 0);while (k--){int t, a, b;cin >> t >> a >> b;if (!a || !b)continue;//0模式初始就能解决g[a][b] = true;//无向图,但建单向边就可以find了}int ans = 0;for (int i = 1; i < n; i++) {mem(st, 0);if (find(i))ans++;}cout << ans << '\n';}return 0;
}

同类型题

思维上更巧妙的最小点覆盖应用

Acwing:泥地


代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 2010, M = 500010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
int match[N], r[N][N], c[N][N], rcnt = 1, ccnt = 1;
//记录每个点所在的泥地连续行、连续列,行对列连边,集合自然分为行集合、列集合,满足二分图性质
//最后求的就是,最少的点覆盖所有的边,即最小点覆盖
bool st[N], g[N][N];
string s[60];
//注意一下数组大小bool find(int x) { //标准匈牙利for (int j = 1; j <= ccnt; j++)if (!st[j] && g[x][j]) {st[j] = true;int t = match[j];if (!t || find(t)) {match[j] = x;return true;}}return false;
}int main() {cinios;cin >> n >> m;for (int i = 0; i < n; i++)cin >> s[i];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {if (j && s[i][j] == '*' && s[i][j - 1] == '.')rcnt++;//一旦遇到干净地面,泥地行编号++if (s[i][j] == '*')r[i][j] = rcnt;//赋予该格行编号}rcnt++;//换行也要++}//对列同样操作,小心bugfor (int i = 0; i < m; i++) { //bug —— i < n, j < mfor (int j = 0; j < n; j++) {if (j && s[j][i] == '*' && s[j - 1][i] == '.')ccnt++;//bug —— s[j][i - 1]if (s[j][i] == '*')c[j][i] = ccnt;//bug —— c[i][j]}ccnt++;}for (int i = 0; i < n; i++)for (int j = 0; j < m; j++)if (s[i][j] == '*') //对于泥地格,建边g[r[i][j]][c[i][j]] = true;int ans = 0;for (int i = 1; i <= rcnt; i++) { //行集合匹配列集合mem(st, 0);if (find(i))ans++;}cout << ans;return 0;
}

——————————————————————————————————————————

二分图最大独立集应用:

最大独立集 是一个点数,指在一个图中选取最多多少个点,可以使得这些点所组成的集合 内部任意两点间没有边

最大独立集 ==(总点数 - 最小点覆盖)

Acwing:骑士放置


代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 110, M = 10010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
PII match[N][N];
bool st[N][N], g[N][N];
int dx[] = { -1,1,2,2,1,-1,-2,-2 }, dy[] = { 2,2,1,-1,-2,-2,-1,1 };//最大匹配数 == 最小点覆盖 == 总点数 - 最大独立集
//
//什么是最大独立集?最大独立集 是一个点数,指在一个图中选取最多多少个点,可以使得这些点所组成的集合 内部任意两点间没有边
//
//因此显然,当你把一个图中 最小点覆盖集合 中的点删去(最少的点覆盖所有的边),剩下的点组成的集合就是 最大独立集(总点数 - 最小点覆盖)//该题问最多能放多少个不能互相攻击的骑士,即两点之间的边不可选取,两点之间的联系必须断开
//断开联系也就相当于删去 最小点覆盖bool find(int x, int y) {for (int i = 0; i < 8; i++) { //走日八个方向int ix = x + dx[i], iy = y + dy[i];if (ix <= 0 || iy <= 0 || ix > n || iy > m || g[ix][iy] || st[ix][iy])continue;st[ix][iy] = true;PII t = match[ix][iy];if (t.fx == 0 || find(t.fx, t.fy)) {match[ix][iy] = { x,y };return true;}}return false;
}int main() {cinios;cin >> n >> m >> k;for (int i = 0; i < k; i++){int a, b;cin >> a >> b;g[a][b] = true;}int ans = n * m - k;//点数 == 总点数 减去 不能放骑士的格子for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)if (i + j & 1 && !g[i][j]) {mem(st, 0);if (find(i, j))ans--;//有一个匹配就相当于有一个点覆盖//减去}cout << ans;//就能得到答案return 0;
}

——————————————————————————————————————————

二分图 最大路径点覆盖 与 最大路径重复点覆盖 应用:

最小路径点覆盖含义:
用最少的点,覆盖图中全部的 不相交 路径,这个路径数是多少?
等于总点数 - 最小点覆盖 / 最大匹配数

最小路径点重复覆盖含义:
用最少的点,覆盖图中全部路径(可以有分叉),这个路径数是多少?
等于 对图做一个传递闭包后的 总点数 - 最小点覆盖 / 最大匹配数

Acwing:捉迷藏


代码:

#include<bits/stdc++.h>
#include<unordered_set>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define ul (u << 1)
#define ur (u << 1 | 1)
#define fx first
#define fy second
//#pragma GCC optimize(2)
//[博客地址](https://blog.csdn.net/weixin_51797626?t=1)
using namespace std;typedef long long ll;
typedef pair<int, int> PII;const int N = 210, M = 10010, MM = 3000010;
int INF = 0x3f3f3f3f, mod = 100003;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
int match[N];
bool st[N], g[N][N];//最小路径点覆盖含义:
//用最少的点,覆盖图中全部的 不相交 路径,这个路径数是多少?
//等于总点数 - 最小点覆盖 / 最大匹配数
//
//最小路径点重复覆盖含义:
//用最少的点,覆盖图中全部路径(可以有分叉),这个路径数是多少?
//等于 对图做一个传递闭包后的 总点数 - 最小点覆盖 / 最大匹配数//此类问题为单向无环图,建二分图比较特殊
//给出的 n 个点作为起点,再虚构 n 个点作为终点,单向边就是左边连右边//连在一条边上的两点显然在一条路径上,这 n 个点中的孤立点就是某路径的终点
//此题要求:选出最多多少个点,保证这些点相互之间都不在同一路径上bool find(int x) {for (int i = 1; i <= n; i++)if (!st[i] && g[x][i]) {st[i] = true;if (match[i] == 0 || find(match[i])) {match[i] = x;return true;}}return false;
}int main() {cinios;cin >> n >> m;while (m--){int a, b;cin >> a >> b;g[a][b] = true;}for (int k = 1; k <= n; k++)//传递闭包for (int i = 1; i <= n; i++)for (int j = 1; j <= n; j++)g[i][j] |= g[i][k] & g[k][j];//让所有点都尽可能匹配到int res = 0;for (int i = 1; i <= n; i++) {mem(st, 0);if (find(i))res++;}cout << n - res;return 0;
}

——————————————————————————————————————————

笔记做吐了ou

二分图(概念、相关算法和题目应用)(全面整理)相关推荐

  1. 第七篇章——垃圾回收概念及相关算法

    垃圾回收--概述 本专栏学习内容来自尚硅谷宋红康老师的视频以及<深入理解JVM虚拟机>第三版 有兴趣的小伙伴可以点击视频地址观看,也可以点击下载电子书 垃圾回收概述 垃圾回收不是Java语 ...

  2. 【Java】数组Array(概念、相关语法、相关算法)

    数组 文章目录 数组 1.数组的相关概念和名词(了解) 2 .数组的相关语法 2.1. 数组的声明 2.2. 数组的初始化 2.3.数组的遍历 2.4. 数组的内存分析 3. 数组的相关算法 3.1. ...

  3. 《大厂算法面试题目与答案汇总,剑指offer等常考算法题思路,python代码》V1.0版...

    为了进入大厂,我想很多人都会去牛客.知乎.CSDN等平台去查看面经,了解各个大厂在问技术问题的时候都会问些什么样的问题. 在看了几十上百篇面经之后,我将算法工程师的各种类型最常问到的问题都整理了出来, ...

  4. 41.虚拟存储器以及相关算法

    虚拟存储器,又有人叫虚拟内存.很容易大家就会把它当做硬件看待. 所以我们先给虚拟存储器定性. 虚拟存储器是计算机系统内存管理的一种技术,它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间 ...

  5. Algorithm:C++语言实现之链表相关算法(链表相加、链表的部分翻转、链表划分、链表去重、重复元素全部删除)

    Algorithm:C++语言实现之链表相关算法(链表相加.链表的部分翻转.链表划分.链表去重.重复元素全部删除) 目录 一.链表 1.1.链表相加 1.2.链表相加 2.1.链表的部分翻转 2.2. ...

  6. Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现

    Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树.二叉查找树的插入节点.二叉查找树的删除.二叉树的遍历.平衡二叉树)C++语言实现 目录 树的基础知识 1.二叉树的遍-前序 ...

  7. 15-垃圾回收相关算法

    垃圾回收相关算法 标记阶段:引用计数算法(Java未使用) 垃圾标记阶段:对象存活判断 在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死 ...

  8. JVM学习笔记之-拉圾回收概述,垃圾回收相关算法

    拉圾回收概述 什么是垃圾 垃圾收集,不是Java语言的伴生产物.早在1960年,第一门开始使用内存动态分配和垃圾收集技术的Lisp语言诞生. 关于垃圾收集有三个经典问题: 哪些内存需要回收? 什么时候 ...

  9. 图论相关算法理解和总结

    晚上学习了一些图论相关算法: 单源最短路径算法: Bellman-Ford 算法: Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shor ...

最新文章

  1. Element 对象表示 XML 文档中的元素。
  2. matlab 条形图与面积图
  3. jquery为图片添加事件
  4. Spring Cache抽象-基于XML的配置声明(基于ConcurrentMap的配置)
  5. mysql+影响的行数+获取_我们如何获得受MySQL查询影响的总行数?
  6. 将Asp.Net页面输出到EXCEL里去
  7. redis(11)--AOF持久化
  8. win7 部署tomcat
  9. Quartz简单实例
  10. oracle把时间段转换成每一天_在家办公难适应?来看看专职外汇交易员的一天
  11. java请编写公共类继承抽象类_(Java相关)怎么理解抽象类,继承和接口?
  12. OC中字符串的提取与替换-四种不同方法实现
  13. HSPF(Hydrological Simulation Program Fortran)模型应用
  14. C语言编写猜数字小游戏
  15. 使用java实现敏感词汇过滤功能
  16. Linux下Oracle移植数据
  17. opencv读取透明图片
  18. MySQL加锁处理分析--何登成
  19. C++ 数据结构——BF算法
  20. 百度熊掌号php,百度熊掌号广受站长关注phpcm网站程序的熊掌号页面插件也火了!...

热门文章

  1. 能不能解释一下什么是COP
  2. 2.7 基本数据类型之间的互相转换 [Swift原创教程]
  3. 微信小程序 高度占满整个屏幕
  4. 详解欧拉计划第395题:毕达哥拉斯树
  5. wxid加好友 wxid转微信号
  6. Linux关闭防火墙 / 开放端口
  7. jenkins节点配置
  8. zsh: command not found: mvn
  9. stm32f407关于独立看门狗各种函数(一)(HAL库)
  10. 关于《永恒之塔私服》收费模式的大胆猜想