当前位置: 首页 > news >正文

数据结构与算法-图论-复习2(差分约束,强连通分量,二分图,LCA,拓扑排序,欧拉路径和欧拉回路)

7. 差分约束

原理

差分约束系统是一种特殊的不等式组,形如 xi​−xj​≤c。可以将其转化为图论中的最短路或最长路问题。

最短路求最大值:当我们要找出满足所有不等式的最大解时,使用最短路算法。对于不等式 xi​−xj​≤c,可以转化为 xi​≤xj​+c,这类似于最短路中的松弛操作 dist[i]≤dist[j]+w(j,i),所以建图时从 j 到 i 连一条权值为 c 的边,然后通过最短路算法求解。

最长路求最小值:当要找出满足所有不等式的最小解时,使用最长路算法。对于不等式 xi​−xj​≥c(可由 xj​−xi​≤−c 变形得到),转化为 xi​≥xj​+c,类似最长路的松弛操作 dist[i]≥dist[j]+w(j,i),建图时从 j 到 i 连一条权值为 −c 的边,用最长路算法求解。

过程

通常需要加入一个超级源点,将超级源点与所有节点相连,边权为 0,以保证图是连通的,然后进行对应的最短路或最长路算法。

代码:

#include <iostream>#include <vector>#include <queue>#include <climits>using namespace std;

const int MAXN = 1005;struct Edge {

    int to, w;};

vector<Edge> adj[MAXN];int dist[MAXN];bool in_queue[MAXN];

// 最长路算法(求最小值)bool spfa(int s, int n) {

    fill(dist, dist + MAXN, INT_MIN);

    fill(in_queue, in_queue + MAXN, false);

    dist[s] = 0;

    queue<int> q;

    q.push(s);

    in_queue[s] = true;

    while (!q.empty()) {

        int u = q.front();

        q.pop();

        in_queue[u] = false;

        for (auto [v, w] : adj[u]) {

            if (dist[v] < dist[u] + w) {

                dist[v] = dist[u] + w;

                if (!in_queue[v]) {

                    q.push(v);

                    in_queue[v] = true;

                }

            }

        }

    }

    return true;}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < m; i++) {

        int i, j, c;

        cin >> i >> j >> c;

        // 求最小值,建图 j -> i, cost: -c

        adj[j].push_back({i, -c});

    }

    // 加入超级源点 0

    for (int i = 1; i <= n; i++) {

        adj[0].push_back({i, 0});

    }

    if (spfa(0, n)) {

        for (int i = 1; i <= n; i++) {

            cout << dist[i] << " ";

        }

        cout << endl;

    }

    return 0;}

8. 有向图的强连通分量

floyd很好理解,本身就是一个用来解决传递闭包的算法
tarjan:通过dfn和low数组,利用dfs的方式找出强连通分量
注意:tarjan得到的序号的逆序就是拓扑序

Floyd 算法

Floyd 算法本身是用于求解全源最短路的算法,但也可以用于解决传递闭包问题。传递闭包是指对于图中的任意两个节点 i 和 j,判断是否存在从 i 到 j 的路径。

代码:

#include <iostream>#include <vector>using namespace std;

const int MAXN = 1005;bool graph[MAXN][MAXN];

void floyd(int n) {

    for (int k = 1; k <= n; k++) {

        for (int i = 1; i <= n; i++) {

            for (int j = 1; j <= n; j++) {

                graph[i][j] = graph[i][j] || (graph[i][k] && graph[k][j]);

            }

        }

    }}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        graph[u][v] = true;

    }

    floyd(n);

    // 输出传递闭包结果

    for (int i = 1; i <= n; i++) {

        for (int j = 1; j <= n; j++) {

            cout << graph[i][j] << " ";

        }

        cout << endl;

    }

    return 0;}

Tarjan 算法

Tarjan 算法通过深度优先搜索(DFS)和两个数组 dfn 和 low 来找出有向图中的强连通分量。

dfn[u]:表示节点 u 在 DFS 过程中的时间戳,即第一次访问节点 u 的顺序。

low[u]:表示节点 u 能够回溯到的最早的节点的时间戳。

代码:

#include <iostream>#include <vector>#include <stack>using namespace std;

const int N = 10005;

vector<int> graph[N];int dfn[N], low[N], index = 0;bool inStack[N];

stack<int> st;int color[N], cnt = 0;

void tarjan(int u) {

    dfn[u] = low[u] = ++index;

    st.push(u);

    inStack[u] = true;

    for (int v : graph[u]) {

        if (!dfn[v]) {

            tarjan(v);

            low[u] = min(low[u], low[v]);

        } else if (inStack[v]) {

            low[u] = min(low[u], dfn[v]);

        }

    }

    if (dfn[u] == low[u]) {

        cnt++;

        while (true) {

            int v = st.top();

            color[v] = cnt;

            st.pop();

            inStack[v] = false;

            if (v == u) break;

        }

    }}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        graph[u].push_back(v);

    }

    for (int i = 1; i <= n; i++) {

        if (!dfn[i]) {

            tarjan(i);

        }

    }

    // 输出每个节点所属的强连通分量编号

    for (int i = 1; i <= n; i++) {

        cout << "Node " << i << " belongs to SCC " << color[i] << endl;

    }

    return 0;}

9. 二分图

染色法判定二分图

二分图是指可以将图中的节点分成两个不相交的集合 A 和 B,使得图中的每条边的两个端点分别属于 A 和 B。染色法的基本思想是对图中的节点进行染色,相邻节点染不同的颜色,如果在染色过程中发现相邻节点颜色相同,则该图不是二分图。

代码:

#include <iostream>#include <vector>using namespace std;

const int MAXN = 10005;

vector<int> adj[MAXN];int color[MAXN];

bool dfs(int u, int c) {

    color[u] = c;

    for (int v : adj[u]) {

        if (color[v] == c) {

            return false;

        }

        if (color[v] == 0) {

            if (!dfs(v, 3 - c)) {

                return false;

            }

        }

    }

    return true;}

bool isBipartite(int n) {

    fill(color, color + MAXN, 0);

    for (int i = 1; i <= n; i++) {

        if (color[i] == 0) {

            if (!dfs(i, 1)) {

                return false;

            }

        }

    }

    return true;}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        adj[u].push_back(v);

        adj[v].push_back(u);

    }

    if (isBipartite(n)) {

        cout << "The graph is bipartite." << endl;

    } else {

        cout << "The graph is not bipartite." << endl;

    }

    return 0;}

匈牙利算法求最大边匹配

匈牙利算法的核心思想是不断寻找增广路径,通过交换匹配边和非匹配边来增加匹配的边数。

情景模拟:

女生开始找男朋友,女生i对m个男生有意思,
她就从头开始问这m个男生:
   如果1,这个男生没有女朋友,她就和她组成情侣,
   如果2,这个男生有女朋友,他们尝试为他现在的女朋友找一个新的并且这个男生的女朋友中意的新的男朋友。
如果上面的两次尝试都失败了,她就去看下一个她中意的。
如果逛了一圈都没有她中意的,她就是一个剩女了
最大边匹配,最小路径点覆盖,最大独立集,最小路径重复点覆盖概念是什么。
他们的关系:最大边匹配=最小路径点覆盖,  最大独立集=最小路径重复点覆盖=点总数-最大匹配边

代码:

#include <iostream>#include <vector>#include <cstring>using namespace std;

const int MAXN = 1005;

vector<int> adj[MAXN];int match[MAXN];bool vis[MAXN];

bool dfs(int u) {

    for (int v : adj[u]) {

        if (!vis[v]) {

            vis[v] = true;

            if (match[v] == 0 || dfs(match[v])) {

                match[v] = u;

                return true;

            }

        }

    }

    return false;}

int hungarian(int n) {

    int ans = 0;

    memset(match, 0, sizeof(match));

    for (int i = 1; i <= n; i++) {

        memset(vis, false, sizeof(vis));

        if (dfs(i)) {

            ans++;

        }

    }

    return ans;}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        adj[u].push_back(v);

    }

    int max_match = hungarian(n);

    cout << "The maximum matching size is: " << max_match << endl;

    return 0;}

相关概念

最大边匹配:二分图中匹配边的最大数量。

最小路径点覆盖:在有向无环图中,用最少的不相交路径覆盖所有节点。对于二分图,最大边匹配数等于最小路径点覆盖数。

最大独立集:图中最大的节点集合,使得集合中任意两个节点之间没有边相连。最大独立集的节点数等于节点总数减去最大匹配边数。

最小路径重复点覆盖:在有向图中,用最少的路径覆盖所有节点,路径可以相交。最小路径重复点覆盖数等于最大独立集的节点数。

10. LCA(最近公共祖先)

向上标记法

向上标记法的基本思想是先从节点 a 开始,将其到根节点的路径上的所有节点标记,然后从节点 b 开始向上遍历,第一个遇到的已标记节点就是 a 和 b 的最近公共祖先。

代码:

#include <iostream>#include <vector>using namespace std;

const int MAXN = 10005;

vector<int> adj[MAXN];bool vis[MAXN];int parent[MAXN];

void dfs(int u, int p) {

    parent[u] = p;

    for (int v : adj[u]) {

        if (v != p) {

            dfs(v, u);

        }

    }}

int lca(int a, int b) {

    // 标记 a 到根节点的路径

    while (a) {

        vis[a] = true;

        a = parent[a];

    }

    // 从 b 开始向上遍历,找到第一个已标记的节点

    while (b) {

        if (vis[b]) {

            return b;

        }

        b = parent[b];

    }

    return -1;}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < n - 1; i++) {

        int u, v;

        cin >> u >> v;

        adj[u].push_back(v);

        adj[v].push_back(u);

    }

    dfs(1, 0);

    for (int i = 0; i < m; i++) {

        int a, b;

        cin >> a >> b;

        fill(vis, vis + MAXN, false);

        int anc = lca(a, b);

        cout << "The LCA of " << a << " and " << b << " is: " << anc << endl;

    }

    return 0;}

倍增算法

倍增算法通过预处理一个二维数组 f[u][i] 表示节点 u 向上跳 2i 步到达的节点,然后利用二进制拆分的思想,快速找到两个节点的最近公共祖先。

代码:

#include <bits/stdc++.h>using namespace std;const int N = 40010, M = 17;int n, m;

unordered_map<int, vector<int>> e;int f[N][M] = {0};int root = 0;int dis[N];

// 预处理数组void bz() {

    memset(dis, 0x3f, sizeof dis);

    dis[0] = 0;

    dis[root] = 1;

    queue<int> q;

    q.push(root);

    while (q.size()) {

        int u = q.front();

        q.pop();

        for (int v : e[u]) {

            if (dis[v] > dis[u]) {

                dis[v] = dis[u] + 1;

                q.push(v);

                f[v][0] = u;

                for (int i = 1; i <= 15; i++) {

                    f[v][i] = f[f[v][i - 1]][i - 1];

                }

            }

        }

    }}

int get(int x, int y) {

    if (dis[x] < dis[y]) swap(x, y);

    for (int i = 15; i >= 0; i--) {

        if (dis[f[x][i]] >= dis[y]) {

            x = f[x][i];

        }

    }

    if (x == y) return x;

    for (int k = 15; k >= 0; k--) {

        if (f[x][k] != f[y][k]) {

            x = f[x][k];

            y = f[y][k];

        }

    }

    return f[x][0];}

int main() {

    cin >> n;

    for (int i = 0; i < n; i++) {

        int a, b;

        scanf("%d%d", &a, &b);

        if (b == -1) root = a;

        else {

            e[a].push_back(b);

            e[b].push_back(a);

        }

    }

    bz();

    cin >> m;

    for (int i = 0; i < m; i++) {

        int u, v;

        scanf("%d%d", &u, &v);

        int anc = get(u, v);

        if (anc == u) cout << 1 << endl;

        else if (anc == v) cout << 2 << endl;

        else cout << 0 << endl;

    }

    return 0;}

Tarjan 算法

初始化:

对给定的树进行预处理,将每个节点的初始状态设置为未遍历(状态 3),并查集的每个元素的父节点初始化为自身,代表每个节点初始时属于独立的集合。

记录所有需要查询最近公共祖先的节点对,以便后续处理。

深度优先搜索:

从树的根节点开始进行深度优先搜索。

当访问到一个节点时,将其状态设置为已遍历但子节点未回溯完(状态 2),即该节点已进入系统栈。

按照从左到右的顺序递归遍历该节点的所有子节点。在递归返回后,说明该子节点的子树已经全部遍历完毕,将该子节点的状态设置为已遍历且子节点全部回溯完(状态 1),同时将子节点所在的并查集合并到当前节点所在的并查集(即将子节点的并查集代表元素设置为当前节点)。

对于每个与当前节点相关的查询对(u,v)或(v,u):

如果u搜索到v已经处于状态 1(即已遍历且子节点全部回溯完),则通过并查集查找u或v所在集合的代表元素,这个代表元素就是u和v的最近公共祖先。因为此时它们在系统栈中的共同祖先节点,通过并查集的合并操作,已经成为了它们所在集合的代表元素。

将找到的最近公共祖先记录下来,用于后续输出或其他处理。

输出结果:

遍历所有的查询对,根据记录的最近公共祖先信息,输出每对节点的最近公共祖先。

代码:

#include <iostream>#include <vector>#include <utility>using namespace std;

const int MAXN = 10005;

vector<pair<int, int>> adj[MAXN];

vector<pair<int, int>> query[MAXN];int res[MAXN];int n, m;int p[MAXN];int st[MAXN];int dep[MAXN];

int find(int x) {

    if (x != p[x]) p[x] = find(p[x]);

    return p[x];}

void tarjan(int u) {

    st[u] = 2;

    for (auto [v, w] : adj[u]) {

        if (!st[v]) {

            dep[v] = dep[u] + 1;

            p[v] = u;

            tarjan(v);

        }

    }

    int pu = find(u);

    for (auto [v, id] : query[u]) {

        if (st[v] == 1) {

            res[id] = dep[u] + dep[v] - 2 * dep[pu];

        }

    }

    st[u] = 1;}

int main() {

    cin >> n >> m;

    for (int i = 1; i <= n; i++) {

        p[i] = i;

    }

    for (int i = 0; i < n - 1; i++) {

        int u, v, w;

        cin >> u >> v >> w;

        adj[u].emplace_back(v, w);

        adj[v].emplace_back(u, w);

    }

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        query[u].emplace_back(v, i);

        query[v].emplace_back(u, i);

    }

    tarjan(1);

    for (int i = 0; i < m; i++) {

        cout << "The distance between the LCA of query " << i + 1 << " is: " << res[i] << endl;

    }

    return 0;}

11. 拓扑排序

Kahn 算法

Kahn 算法的基本思想是不断选择入度为 0 的节点,并将其从图中删除,同时更新其邻接节点的入度。

代码:

#include <iostream>#include <vector>#include <queue>using namespace std;

vector<int> topologicalSort(int n, vector<vector<int>>& graph) {

    vector<int> inDegree(n, 0);

    vector<int> result;

    queue<int> q;

    for (int i = 0; i < n; ++i) {

        for (int neighbor : graph[i]) {

            ++inDegree[neighbor];

        }

    }

    for (int i = 0; i < n; ++i) {

        if (inDegree[i] == 0) {

            q.push(i);

        }

    }

    while (!q.empty()) {

        int u = q.front();

        q.pop();

        result.push_back(u);

        for (int v : graph[u]) {

            --inDegree[v];

            if (inDegree[v] == 0) {

                q.push(v);

            }

        }

    }

    if (result.size() != n) {

        return {};

    }

    return result;}

int main() {

    int n, m;

    cin >> n >> m;

    vector<vector<int>> graph(n);

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        graph[u].push_back(v);

    }

    vector<int> topo = topologicalSort(n, graph);

    if (topo.empty()) {

        cout << "The graph contains a cycle." << endl;

    } else {

        for (int node : topo) {

            cout << node << " ";

        }

        cout << endl;

    }

    return 0;}

12. 欧拉路径和欧拉回路

概念

有向图中:

欧拉路径:

定义:在有向图中,从一个顶点出发,经过每条边恰好一次,并且遍历所有顶点的路径称为有向图的欧拉路径。

特征:有向图存在欧拉路径,当且仅当该图是连通的,且除了两个顶点外,其余顶点的入度等于出度。这两个特殊顶点中,一个顶点的入度比出度大 1(终点),另一个顶点的出度比入度大 1(起点)。如果全部点的入度和出度数都是相等的也可以。

欧拉回路:

定义:在有向图中,从一个顶点出发,经过每条边恰好一次,最后回到起始顶点的路径称为有向图的欧拉回路。

特征:有向图存在欧拉回路,当且仅当该图是连通的,且所有顶点的入度等于出度。

无向图中:

欧拉路径:

定义:在无向图中,从一个顶点出发,经过每条边恰好一次,并且遍历所有顶点的路径称为无向图的欧拉路径。

特征:无向图存在欧拉路径,当且仅当该图是连通的,且图中奇度顶点(度数为奇数的顶点)的个数为 0 或 2。若奇度顶点个数为 0,则可以从任意顶点出发;若奇度顶点个数为 2,则必须从其中一个奇度顶点出发,到另一个奇度顶点结束。

欧拉回路:

定义:在无向图中,从一个顶点出发,经过每条边恰好一次,最后回到起始顶点的路径称为无向图的欧拉回路。

特征:无向图存在欧拉回路,当且仅当该图是连通的,且所有顶点的度数均为偶数。

有向图的欧拉路径

代码:

#include <bits/stdc++.h>using namespace std;const int N = 100005;

vector<int> g[N];int in[N];int out[N];int s[N];int top = 0;

void dfs(int u) {

    while (!g[u].empty()) {

        int v = g[u].back();

        g[u].pop_back();

        dfs(v);

    }

    s[++top] = u;}

int main() {

    int n, m;

    cin >> n >> m;

    for (int i = 0; i < m; i++) {

        int u, v;

        cin >> u >> v;

        g[u].push_back(v);

        in[v]++;

        out[u]++;

    }

    for (int i = 1; i <= n; i++) {

        sort(g[i].begin(), g[i].end(), greater<int>());

    }

    int start = 1;

    int cnt = 0;

    bool flag = true;

    for (int i = 1; i <= n; i++) {

        if (out[i] - in[i] == 1) {

            start = i;

            cnt++;

        } else if (out[i] - in[i] == -1) {

            cnt++;

        } else if (out[i] != in[i]) {

            flag = false;

            break;

        }

    }

    if (cnt != 0 && cnt != 2) {

        flag = false;

    }

    if (!flag) {

        cout << "No" << endl;

    } else {

        dfs(start);

        while (top) {

            cout << s[top--];

            if (top) {

                cout << " ";

            }

        }

        cout << endl;

    }

    return 0;}

相关文章:

数据结构与算法-图论-复习2(差分约束,强连通分量,二分图,LCA,拓扑排序,欧拉路径和欧拉回路)

7. 差分约束 原理 差分约束系统是一种特殊的不等式组&#xff0c;形如 xi​−xj​≤c。可以将其转化为图论中的最短路或最长路问题。 最短路求最大值&#xff1a;当我们要找出满足所有不等式的最大解时&#xff0c;使用最短路算法。对于不等式 xi​−xj​≤c&#xff0c;可以…...

git强制更新本地分支

你的需求是希望 自动拉取所有远程分支&#xff0c;并且在分支间存在冲突时 自动覆盖本地内容&#xff08;不保留差异&#xff09;。以下是优化后的解决方案&#xff1a; 最终解决方案&#xff08;全自动强制覆盖&#xff09; git fetch --all && for branch in $(git …...

PH热榜 | 2025-04-09

1. EZsite AI 标语&#xff1a;构建能够秒级产生收入的人工智能应用。 介绍&#xff1a;EZsite AI 让任何人都能轻松创建专业的网站和应用&#xff0c;不需要编写代码。它自动保存您的数据库信息&#xff0c;内置的 AI 聊天机器人能帮助您捕获潜在客户&#xff0c;并且通过 A…...

进度管理__制订进度计划_资源平衡和资源平滑

本文讲解的资源平衡与资源平滑&#xff0c;是制订进度计划的工具与技术的第3项&#xff1a; 资源优化。 1. 资源平衡 资源平衡是为了在资源需求与资源供给之间取得平等&#xff0c; 根据资源制约因素对开始日期和完成日期进行调整的一种技术。 如果共享资源或关键资源只在特定…...

【力扣hot100题】(080)爬楼梯

让我们掌声恭迎动态规划的始祖—— 最基础的动态规划&#xff0c;原始方法是维护一个数组&#xff0c;每次记录到该阶梯的方案数量&#xff0c;每次的数量是到上一个阶梯的方案数量加上到上上一阶梯的方案数量&#xff0c;因为只有两种走法。 进阶可以优化空间复杂度&#xf…...

redis_exporter服务安装并启动

redis_exporter服务安装并启动 1、介绍2、下载redis_exporter3、解压缩文件4、启动redis_exporter服务 1、介绍 Redis Exporter 是 Prometheus 官方推荐的 Redis 监控数据导出工具&#xff0c;用于将 Redis 实例的性能指标暴露为 Prometheus 可抓取的格式。 2、下载redis_exp…...

Spring Security 的核心配置项详解,涵盖认证、授权、过滤器链、HTTP安全设置等关键配置,结合 Spring Boot 3.x 版本最佳实践

以下是 Spring Security 的核心配置项详解&#xff0c;涵盖认证、授权、过滤器链、HTTP安全设置等关键配置&#xff0c;结合 Spring Boot 3.x 版本最佳实践&#xff1a; 1. 核心注解与配置类 (1) 启动安全配置 // 启动Web安全配置&#xff08;推荐方式&#xff09; Configura…...

Spring Boot 3.x 下 Spring Security 的执行流程、核心类和原理详解,结合用户描述的关键点展开说明,并以表格总结

以下是 Spring Boot 3.x 下 Spring Security 的执行流程、核心类和原理详解&#xff0c;结合用户描述的关键点展开说明&#xff0c;并以表格总结&#xff1a; 1. Spring Security 核心原理 Spring Security 通过 Filter 链 实现安全控制&#xff0c;其核心流程如下&#xff1a…...

[leetcode]判断质数

一.判断质数 1.1 什么是质数 质数&#xff08;素数&#xff09;就是只可以被自己和1整除的数叫做素数/质数 1.2判断方法 #include<bits/stdc.h> using namespace std; bool isPrime(int num) { if(num < 1) { return false;//a number less of …...

【结肠息肉AI论文集】Cross-level Feature Aggregation Network for Polyp Segmentation

标注&#xff1a;同样是一期结肠息肉论文写作评鉴 摘要 从结肠镜图像中准确分割息肉在结直肠癌的诊断和治疗中起着关键作用。尽管在息肉分割领域已经取得了一定的成效&#xff0c;但仍存在诸多挑战。息肉通常具有多种大小和形状&#xff0c;并且息肉与其周围区域之间没有明显…...

Redis缓存之预热、击穿、穿透、雪崩

面试切入点 缓存预热 什么是预热&#xff1f; mysql假如新增100条记录&#xff0c;一般默认以mysql为准作为底单数据&#xff0c;如何同步到redis(布隆过滤器)&#xff0c;这100条合法数据&#xff1f;&#xff1f; 为什么需要预热&#xff1f; mysql有100条新记录&#xff0…...

C++字符串复习

C字符串复习 前言 为了保证复习高效&#xff0c;以下不包括很简单的内容&#xff0c;例如cin。 C类型字符、字符串 输入方法 **char c getchar()**输入单个字符 string类型字符串 输入方法 getline(cin, str) 整行输入 常用方法 s.substr(pos, len)&#xff1a;截取字…...

centos7安装mysql5.7.44

一、下载 下载地址&#xff1a;https://downloads.mysql.com/archives/community/ 二、安装 1、解压 tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz 2、创建mysql用户组和用户 # 创建mysql用户组 groupadd mysql# 创建用户并添加到mysql用户组中 useradd -r -g m…...

内存分配中的堆(Memory Heap)详解

在计算机科学中&#xff0c;"堆"这个术语确实容易让人混淆&#xff0c;因为它同时用于描述两种完全不同的概念&#xff1a;数据结构中的堆和内存管理中的堆。上次我们讨论了数据结构中的堆&#xff0c;今天我将详细解释内存分配中的堆&#xff08;Memory Heap&#x…...

【大模型理论篇】关于生成式模型中联合分布概率学习必要性以及GPT是生成式模型的讨论

1. 背景 之前我们在《生成式模型与判别式模型对比(涉及VAE、CRF的数学原理详述)》以及《生成式模型算法原理深入浅出&#xff08;涉及Stable Diffusion、生成对抗网络、高斯混合模型、隐马尔可夫模型、朴素贝叶斯等算法原理分析及生成式模型解释&#xff09;》中&#xff0c;我…...

LeetCode738☞单调递增的数字

关联LeetCode题号738 本题特点 贪心&#xff0c;贪心在如果非单调递增&#xff0c;则想要保证数字整体最大&#xff0c;那低数位一定为9&#xff08;所有数字中最大的&#xff09; 本题思路 从后向前遍历&#xff0c;如果递增则 什么都不做如果非递增&#xff0c;增非递增位…...

本节课课堂总结

课堂总结&#xff1a; Spark运行架构&#xff1a; 运行架构&#xff1a; Spark 框架的核心是一个计算引擎&#xff0c;整体来说&#xff0c;它采用了标准 master-slave 的结构。 如下图所示&#xff0c;它展示了一个 Spark 执行时的基本结构。图形中的 Driver 表示 master&…...

MyBatis中特殊符号处理总结

前言 MyBatis 是一款流行的Java持久层框架&#xff0c;广泛应用于各种类型的项目中。因为我们在日常代码 MyBatis 动态拼接语句时&#xff0c;会经常使用到 大于(>,>)、小于(<,<)、不等于(<>、!)操作符号。由于此符号包含了尖括号&#xff0c;而 MyBatis 使用…...

【零基础实战】Ubuntu搭建DVWA漏洞靶场全流程详解(附渗透测试示例)

【零基础实战】Ubuntu搭建DVWA漏洞靶场全流程详解&#xff08;附渗透测试示例&#xff09; 一、DVWA靶场简介 DVWA&#xff08;Damn Vulnerable Web Application&#xff09;是专为网络安全学习者设计的漏洞演练平台&#xff0c;包含SQL注入、XSS、文件包含等10大Web漏洞模块&…...

若依前后端分离版本从mysql切换到postgresql数据库

一、修改依赖&#xff1a; 修改admin模块pom.xml中的依赖,屏蔽或删除mysql依赖&#xff0c;增加postgresql依赖。 <!-- Mysql驱动包 --> <!--<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId> &l…...

【补题】Codeforces Round 974 (Div. 3) E. Rendez-vous de Marian et Robin

题意&#xff1a;给个图&#xff0c;两个人分别从点1和点n出发&#xff0c;问最早在哪个点可以相遇&#xff0c;其中某些点有马&#xff0c;骑上去之后可以在接下来剩余的时间内都可以将路程所需时间缩短一半。 关于题目数据见原题&#xff0c;这里说明太累了想偷懒Problem - 2…...

MySQL集群技术

当有数据时添加slave2 #从master节点备份数据 mysqldump -uroot -ptiminglee 1 > timinglee.sql 生产环境中备份时需要锁表&#xff0c;保证备份前后的数据一致 mysql> FLUSH TABLES WITH READ LOCK; 备份后再解锁 mysql> UNLOCK TABLES; mysqldump命令备份的数…...

Java 中的字节码

&#x1f50d; 什么是 Java 字节码&#xff08;Bytecode&#xff09;&#xff1f; 字节码是 Java 源码&#xff08;.java 文件&#xff09;被编译后生成的中间代码&#xff08;.class 文件&#xff09;&#xff0c;它不是机器码&#xff0c;而是一种 面向 JVM 的指令集。 可以…...

json 转 txt 用于 yolo 训练(可适用多边形标注框_python)

json 转 txt 用于 yolo 训练&#xff08;可适用多边形标注框_python&#xff09; import json import os import argparse from tqdm import tqdmdef convert_label_json(json_dir, save_dir, classes):json_paths os.listdir(json_dir)classes classes.split(,)for json_pa…...

SQL注入(SQL Injection)

目录 SQL注入(SQL Injection)是什么SQL注入的危害SQL注入的常见方式1. 经典注入(Error-Based Injection)2. 联合查询注入(Union-Based Injection)3. 时间盲注(Time-Based Blind Injection)4. 布尔盲注(Boolean-Based Blind Injection)5. 堆叠注入(Stacked Queries I…...

智慧厨房的秘密:当大模型遇见智能体

智慧厨房的秘密&#xff1a;当大模型遇见智能体 想象一下&#xff0c;一家餐厅里&#xff0c;顾客点了一份特别定制的菜肴。厨师不仅需要知道如何制作这道菜&#xff0c;还得根据当天的食材情况灵活调整配方&#xff0c;甚至考虑到顾客的口味偏好做出微调。这一切背后&#xf…...

IDEA遇到问题汇总

问题1&#xff1a;【异常】IDEA中报错&#xff1a;无效的目标发行版本 IDEA 报错&#xff1a;无效的源发行版-CSDN博客 【异常】IDEA中报错&#xff1a;无效的目标发行版本-CSDN博客 原因是&#xff1a;版本不兼容不一致&#xff0c;需要修改jdk、maven、以及目标字节码使之相一…...

状态管理组件Pinia 简介与底层原理 、Pinia 与其他状态管理库对比、Vue3 + Element Plus + Pinia 安装配置详解

一、Pinia 简介与底层原理 1. Pinia 简介 Pinia 是 Vue3 官方推荐的状态管理库&#xff0c;由 Vue 核心团队开发&#xff0c;旨在替代 Vue2 的 Vuex。其核心目标是提供一种更简洁、直观的状态管理方案&#xff0c;同时充分利用 Vue3 的响应式系统和 Composition API。 2. 底…...

本地部署 opik

本地部署 opik 1. 安装2. 访问 1. 安装 克隆代码&#xff0c; git clone https://github.com/comet-ml/opik.git使用 Docker compose 启动&#xff0c; cd opik/deployment/docker-compose docker compose up -d2. 访问 启动后&#xff0c;您可以在浏览器中访问 localhost:…...

操作系统之进程与线程的理解(一)

对进程的理解 进程是可以并发执行的程序在某个数据集合上的运行过程&#xff0c;是系统进行资源分配和调度的基本单位。进程由三部分组成&#xff0c;程序&#xff0c;数据和进程控制块&#xff08;简称PCB&#xff09;。简单的说&#xff0c;进程就是程序的一次执行 为确保进…...

JS 箭头函数

只能用于声明函数表达式更简洁。替代匿名函数 设置取消点击事件的默认行为 在这里插入图片描述...

Mb,Kb,byte,bits

1MB1024KB; 1KB1024byte(字节&#xff09;&#xff1b; 1byte8bits&#xff08;位&#xff09;&#xff1b; 小蓝准备用 256MB 的内存空间开一个数组&#xff0c;数组的每个元素都是 32 位 二进制整数&#xff0c;如果不考虑程序占用的空间和维护内存需要的辅助空间&#xf…...

x265 中 aqMode 和 hevcAq 的深度解析与应用技巧

aqMode 和 hevcAq 介绍 在 x265 中基本继承了 x264 中 aqmode 的思想,此外还引入了 hevcAq 算法工具,在 x265_param 结构体中有这两个参数变量开关相关解释。从声明注释可以理解,aqMode 和 x264 中 aqmode 的思想完全相似,也扩展了些功能,属于通用型自适应量化方法,基于 …...

(一)基于云平台微调大模型,以deepseek-coder-6.7b为例

一、租借rtx4090卡并创建示例 如下图&#xff0c;我们进入jupyter界面&#xff0c;然后创建笔记本 二、提前下载好模型到本地 为了节省时间&#xff0c;我们需要提前下好模型deepseek-ai/deepseek-coder-6.7b-instruct&#xff0c;然后再上传到autodl上直接本地加载。 下载方…...

【Docker基础】全面解析 Docker 镜像:构建、使用与管理

文章目录 一、Docker 镜像&#xff08;Docker Image&#xff09;详解1.1 Docker 镜像的结构1.2 Docker 镜像的每一层&#xff08;Layer&#xff09;1.3 镜像的构建过程1.4 镜像的使用1.5 镜像的优势 二、为什么需要镜像三、镜像命令3.1 命令清单3.2 详细解释 四、docker 操作案…...

3. git config

文章目录 基本概述配置级别基本用法设置配置项查看配置项删除配置项 常用配置项 基本概述 git config 的作用是&#xff1a;设置用户信息、编辑器、别名、仓库行为等。 配置级别 级别作用范围配置文件路径命令选项仓库级别&#xff08;Local&#xff09;当前仓库.git/config…...

docker 运行自定义化的服务-前端

运行自定义化的前端服务 具体如下&#xff1a; ①打包前端项目&#xff0c;形成dist包 ②编写dockerfile文件&#xff0c;文件内容如下&#xff1a; # 基础镜像(镜像名:版本号TAG) FROM nginx:1.0 # 镜像作者和相关元数据 LABEL maintainer"Atb" \version"1.0…...

error: RPC failed; HTTP 408 curl 22 The requested URL returned error: 408

在git push时报错&#xff1a;error: RPC failed; HTTP 408 curl 22 The requested URL returned error: 408 原因&#xff1a;可能是推送的文件太大&#xff0c;要么是缓存不够&#xff0c;要么是网络不行。 解决方法&#xff1a; 将本地 http.postBuffer 数值调整到500MB&…...

JMH 基准测试实战:Java 性能对比的正确打开方式!

&#x1f4d6; 摘要 在Java开发中&#xff0c;我们经常需要比较不同实现方式的性能差异。但如何科学、准确地进行性能测试呢&#xff1f;本文将带你深入理解JMH&#xff08;Java Microbenchmark Harness&#xff09;工具&#xff0c;通过实战演示如何正确编写和运行基准测试&a…...

etf可以T+0交易吗?

在我国的A股市场中&#xff0c;部分ETF基金支持T0交易&#xff0c;这为投资者提供了更灵活的交易策略。 支持T0交易的ETF基金类型包括&#xff1a; 货币型ETF&#xff1a;主要投资于货币市场工具&#xff0c;如短期债券和银行存款&#xff0c;具有较高的流动性。 债券型ETF&…...

解决问题:Vscode 自动更新不匹配远程服务器版本

避免自动更新&#xff1a; 1. 打开&#xff1a;文件 - 首选项 - 设置 - 应用程序 - 更新&#xff1b; 2. 设置下列选项&#xff1a; 如果已自动更新&#xff0c;如何回退至原有的历史版本 &#xff1a; 去官网下载所需的历史版本&#xff0c;然后直接按流程安装&#xff0c;…...

【Leetcode-Hot100】盛最多水的容器

题目 解答 目的是求面积最大&#xff0c;面积是由两个下标和对应的最小值得到&#xff0c;因此唯一的问题就是如何遍历这两个下标。我采用begin和end两个变量&#xff0c;确保begin是小于end的&#xff0c;使用它们二者求面积&#xff0c;代码如下&#xff1a; 很不幸 出错了…...

FFMEPG常见命令查询

基本参数 表格1&#xff1a;主要参数 参数说明-i设定输入流-f设定输出格式(format) 高于后缀名-ss开始时间-t时间长度codec编解码 表格2&#xff1a;音频参数 参数说明-aframes设置要输出的音频帧数-f音频帧深度-b:a音频码率-ar设定采样率-ac设定声音的Channel数-acodec设定…...

欢迎来到 Codigger Store:Boby周边专区

亲爱的 Codigger 用户们&#xff0c;感谢你们一直以来的支持与热爱&#xff01;你们的每一次代码跳跃、每一次项目成功&#xff0c;都离不开你们对编程的热情和对 Codigger 的信任。为了回馈大家的厚爱&#xff0c;我们在 Codigger Store 中特别开设了 Boby 周边专区&#xff0…...

决策树模型

决策树(TDS) 注意1&#xff1a;决策树有很多种算法&#xff0c;比如&#xff1a;ID3算法&#xff0c;C4.5算法&#xff0c;CART算法&#xff0c;这三个算法的区别是选择最优划分属性的方法不同&#xff0c;第一个是根据信息增益来选&#xff1b;第二个是找出信息增益高于平均水…...

解锁深度学习激活函数

在深度学习的广袤天地里&#xff0c;激活函数宛如隐匿于神经网络架构中的神奇密码&#xff0c;掌控着模型学习与表达的关键力量。今天&#xff0c;就让我们一同深入探究这些激活函数的奇妙世界&#xff0c;揭开它们神秘的面纱。 一、激活函数为何不可或缺&#xff1f; 想象一…...

Kubernetes 深入浅出系列 | 容器剖析之容器安全

目录 1、容器真的需要privileged权限吗?一、什么是 --privileged 权限&#xff1f;二、privileged 的风险到底有多大&#xff1f;三、常见需求场景及更安全的替代方式四、如何判断容器是否真正需要特权&#xff1f; 2、不以 Root 用户运行容器&#xff0c;真的更安全吗&#x…...

Spring Boot应用中可能出现的Full GC问题

Full GC的原理与触发条件 原理 标记-清除&#xff1a;首先遍历所有对象&#xff0c;标记可达的对象&#xff0c;然后清除不可达的对象。复制算法&#xff1a;将内存分为两部分&#xff0c;每次只使用其中一部分。当这部分内存用完时&#xff0c;将存活的对象复制到另一部分&a…...

Maven 的安装与配置(IDEA)

2025/4/9 向 一、什么是Maven Maven 是一个基于项目对象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;概念的项目构建工具&#xff08;所以就是一个工具&#xff09;&#xff0c;它主要用于自动化项目的构建过程&#xff0c;包括编译、测试、打包、部署等…...

软考中级-软件设计师 2022年下半年上午题真题解析:通关秘籍+避坑指南

&#x1f4da; 目录&#xff08;快速跳转&#xff09; 选择题&#xff08;上午题&#xff09;&#xff08;每题1分&#xff0c;共75分&#xff09;一、 计算机系统基础知识 &#x1f5a5;️&#x1f4bb; 题目1&#xff1a;计算机硬件基础知识 - RISC&#xff08;精简指令集计算…...