【图的应用二:最短路径】- 用 C 语言实现迪杰斯特拉算法和弗洛伊德算法
目录
一、最短路径
二、迪杰斯特拉算法
三、弗洛伊德算法
一、最短路径
假若要在计算机上建立一个交通咨询系统,则可以采用图的结构来表示实际的交通网络。如下图所示,图中顶点表示城市,边表示城市间的交通联系。

这个咨询系统可以回答旅客提出的各种问题。例如,一位旅客要从 A 城到 B 城,他希望选择一条中转次数最少的路线。假设图中每一站都需要换车,则这个问题反映到图上就是找一条顶点 A 到顶点 B 所包含边的数目最少的路径。只需从顶点 A 出发对图做广度优先搜索,一旦遇到顶点 B 就终止,由此所得的广度优先生成树上,从根顶点 A 到顶点 B 的路径就是中转次数最少的路径。
但是,这只是一类最简单的图的最短路径问题。有时,对于旅客来说,可能更关心的是节省交通费用;而对于司机来说,里程和速度则是他们感兴趣的信息。为了在图上表示有关信息,可对边赋予权,权的值表示两城市间的距离,或途中所需时间,或交通费用等。此时路径长度的度量就不再是路径上边的数目,而是路径上边的权值之和。考虑到交通图的有向性,例如,汽车的上山和下山,轮船的顺水和逆水,所花费的时间或代价就不相同,所以交通网往往是用带权有向网表示。在带权有向网中,习惯上称路径上的第一个顶点为源点(Source),最后一个顶点为终点(Destination)。
下面主要讨论两种最常见的最短路径问题:一种是求从某个源点到其余各顶点的最短路径,另一种是求每一对顶点之间的最短路径。
二、迪杰斯特拉算法
单源点的最短路径问题:给定带权有向图 G 和源点 v0,求从 v0 到 G 中其余各顶点的最短路径。
迪杰斯特拉(Dijkstra)提出了一个按路径长度递增的次序产生最短路径的算法,称为迪杰斯特拉算法。
(1) 迪杰斯特拉算法的求解过程:
对于网 N = (V, E),将 N 中的顶点分为两组:
第一组 S:已求出的最短路径的终点集合(初始时只包含源点 v0)。
第二组 V - S:尚未求出的最短路径的顶点集合(初始时为 V - {v0})。
算法将按各顶点与 v0 间最短路径长度递增的次序,逐个将集合 V - S 中的顶点加入到集合 S 中去。在这个过程中,总保持从 v0 到集合 S 中各顶点的路径长度始终不大于到集合 V - S 中各顶点的路径长度。
这种求解方法能确保是正确的,因为假设 S 为已求得最短路径的终点的集合,则可证明:下一条最短路径(设其终点为 x)或是边 (v0, x),或是中间只是经过 S 中的顶点而最后到达顶点 x 的路径。
这可用反证法来证明。假设此路径上有一个顶点不在 S 中,则说明存在一条终点不在 S 而长度比此路径短的路径。但是,这是不可能的,因为算法是按路径长度递增的次序来产生最短路径的,故长度比此路径短的所有路径均已产生,它们的终点必定在 S 中,即假设不成立。
(2) 迪杰斯特拉算法的实现:
假设用带权的邻接矩阵 arcs 来表示带权有向网 G。
算法的实现要引入以下辅助的数据结构:
-
一维数组 S[i]:记录从源点 v0 到终点 vi 是否已被确定最短路径长度,true 表示确定,false 表示尚未确定。
-
一维数组 Path[i]:记录从源点 v0 到终点 vi 的当前最短路径上 vi 的直接前驱顶点序号。其初值为:如果从 v0 到 vi 有弧,则 Path[i] 为 v0;否则为 -1。
-
一维数组 D[i]:记录从源点 v0 到终点 vi 的当前最短路径长度。其初值为:如果从 v0 到 vi 有弧,则 D[i] 为弧上的权值;否则为
。
最短路径为 D[k] = Min{ D[i] | },求得从源点到 vk 的最短路径后,将 vk 加入到第一组顶点集 S 中。
每当加入一个新的顶点到顶点集 S,对第二组剩余的各个顶点而言,多了一个 "中转" 顶点,从而多了一个 "中转" 路径,所以要对第二组剩余的各个顶点的最短路径长度进行更新。
原来从 v0 到 vi 的最短路径长度为 D[i],加入 vk 之和,以 vk 作为中间顶点的 "中转" 路径长度为:D[k] + G.arcs[k][i],若 D[k] + G.arcs[k][i] < D[i],则用 D[k] + G.arcs[k][i] < D[i] 取代 D[i]。
AMGraph.h:
#pragma once
typedef char VertexType;
typedef int ArcType;
#define DEFAULT_CAPACITY 2
typedef struct AMGraph
{VertexType* vertices;ArcType** arcs;int vSize;int aSize;int capacity;
}AMGraph;
void AMGraphInit(AMGraph* pg);
void ShowAdjMatrix(AMGraph* pg);
int GetVertexPos(AMGraph* pg, VertexType v);
void InsertVertex(AMGraph* pg, VertexType v);
void InsertArc(AMGraph* pg, VertexType v1, VertexType v2, ArcType cost);
// 迪杰斯特拉算法
void ShortestPath_DIJ(AMGraph* pg, VertexType v, int* D, int* Path);
AMGraph.c:
#include "AMGraph.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
void AMGraphInit(AMGraph* pg)
{assert(pg);pg->vSize = pg->aSize = 0;pg->capacity = DEFAULT_CAPACITY;
pg->vertices = (VertexType*)malloc(sizeof(VertexType) * pg->capacity);assert(pg->vertices);
pg->arcs = (ArcType**)malloc(sizeof(ArcType*) * pg->capacity);assert(pg->arcs);for (int i = 0; i < pg->capacity; ++i){pg->arcs[i] = (ArcType*)malloc(sizeof(ArcType) * pg->capacity);assert(pg->arcs[i]);for (int j = 0; j < pg->capacity; ++j){if (i == j)pg->arcs[i][j] = 0;elsepg->arcs[i][j] = INT_MAX;}}
}
void ShowAdjMatrix(AMGraph* pg)
{assert(pg);printf(" "); // 输出 3 个空格for (int i = 0; i < pg->vSize; ++i){printf("%c ", pg->vertices[i]);}printf("\n");
for (int i = 0; i < pg->vSize; ++i){printf("%c ", pg->vertices[i]);for (int j = 0; j < pg->vSize; ++j){if (pg->arcs[i][j] == INT_MAX)printf("# "); // 用 # 代替 ∞elseprintf("%-3d", pg->arcs[i][j]);}printf("\n");}
}
int GetVertexPos(AMGraph* pg, VertexType v)
{assert(pg);for (int i = 0; i < pg->vSize; ++i){if (pg->vertices[i] == v)return i;}return -1;
}
void InsertVertex(AMGraph* pg, VertexType v)
{assert(pg);// 考虑是否需要扩容if (pg->vSize == pg->capacity){VertexType* tmp1 = (VertexType*)realloc(pg->vertices, sizeof(VertexType) * 2 * pg->capacity);assert(tmp1);pg->vertices = tmp1;
ArcType** tmp2 = (ArcType**)realloc(pg->arcs, sizeof(ArcType*) * 2 * pg->capacity);assert(tmp2);pg->arcs = tmp2;for (int i = 0; i < pg->capacity; ++i){ArcType* tmp3 = (ArcType*)realloc(pg->arcs[i], sizeof(ArcType) * 2 * pg->capacity);assert(tmp3);pg->arcs[i] = tmp3;for (int j = pg->capacity; j < 2 * pg->capacity; ++j){pg->arcs[i][j] = INT_MAX;}}for (int i = pg->capacity; i < 2 * pg->capacity; ++i){pg->arcs[i] = (ArcType*)malloc(sizeof(ArcType) * 2 * pg->capacity);assert(pg->arcs[i]);for (int j = 0; j < 2 * pg->capacity; ++j){if (i == j)pg->arcs[i][j] = 0;elsepg->arcs[i][j] = INT_MAX;}}
pg->capacity *= 2;}// 插入顶点pg->vertices[pg->vSize++] = v;
}
void InsertArc(AMGraph* pg, VertexType v1, VertexType v2, ArcType cost)
{assert(pg);int pos1 = GetVertexPos(pg, v1);int pos2 = GetVertexPos(pg, v2);if (pos1 == -1 || pos2 == -1)return;
if (pg->arcs[pos1][pos2] != INT_MAX)return;
pg->arcs[pos1][pos2] = cost;++pg->aSize;
}
// 迪杰斯特拉算法的实现
void ShortestPath_DIJ(AMGraph* pg, VertexType v, int* D, int* Path)
{assert(pg);int pos = GetVertexPos(pg, v);if (pos == -1)return;
bool* S = (bool*)malloc(sizeof(bool) * pg->vSize);assert(S);for (int i = 0; i < pg->vSize; ++i){S[i] = false;D[i] = pg->arcs[pos][i];if (i != pos && D[i] != INT_MAX)Path[i] = pos;elsePath[i] = -1; }S[pos] = true;
for (int i = 0; i < pg->vSize - 1; ++i){int min;int k;int flag = 1;for (int j = 0; j < pg->vSize; ++j){if (S[j] != false){continue;}if (flag){min = D[j];k = j;flag = 0;continue;}if (D[j] < min){min = D[j];k = j;}}
S[k] = true;for (int j = 0; j < pg->vSize; ++j){
if (S[j] == false && pg->arcs[k][j] != INT_MAX && D[k] + pg->arcs[k][j] < D[j]){D[j] = D[k] + pg->arcs[k][j];Path[j] = k;}}}
free(S);
}
Test.c:
#include "AMGraph.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{AMGraph g;AMGraphInit(&g);InsertVertex(&g, 'A');InsertVertex(&g, 'B');InsertVertex(&g, 'C');InsertVertex(&g, 'D');InsertVertex(&g, 'E');InsertVertex(&g, 'F');InsertArc(&g, 'A', 'C', 10);InsertArc(&g, 'A', 'E', 30);InsertArc(&g, 'A', 'F', 100);InsertArc(&g, 'B', 'C', 5);InsertArc(&g, 'C', 'D', 50);InsertArc(&g, 'D', 'F', 10);InsertArc(&g, 'E', 'D', 20);InsertArc(&g, 'E', 'F', 60);ShowAdjMatrix(&g);printf("\n");
int* D = (int*)malloc(sizeof(int) * g.vSize);int* Path = (int*)malloc(sizeof(int) * g.vSize);assert(D && Path);ShortestPath_DIJ(&g, 'A', D, Path);
for (int i = 1; i < g.vSize; ++i){if (D[i] == INT_MAX)printf("从 A 到 %c 没有路径!\n", g.vertices[i]);elseprintf("从 A 到 %c 的最短路径长度为:%d\n", g.vertices[i], D[i]);}free(D);free(Path);return 0;
}

三、弗洛伊德算法
求解每一对顶点之间的最短路径有两种方法:其一是分别以图中的每个顶点为源点共调用 n 次迪杰斯特拉算法;其二是采用下面介绍的弗洛伊德(Floyd)算法。两种算法的时间复杂度均为 O(n^3),但后者形式上较简单。
弗洛伊德算法仍然使用带权的邻接矩阵 arcs 来表示有向网 G,求从顶点 vi 到 vj 的最短路径。
算法的实现要引入以下辅助的数据结构:
-
二维数组 D[i][j]:记录顶点 vi 到 vj 之间的最短路径长度。
-
二维数组 Path[i][j]:最短路径上顶点 vj 的前一顶点的序号。
算法步骤:
将 vi 到 vj 的最短路径长度初始化,即 D[i][j] = G.arcs[i][j],然后进行 n 次比较和更新。
-
在 vi 和 vj 间加入顶点 v0,比较 (vi, vj) 和 (vi, v0, vj) 的路径长度,取其中较短者为 vi 到 vj 的中间顶点序号不大于 0 的最短路径。
-
在 vi 和 vj 间加入顶点 v1,得到 (vi, ..., v1) 和 (v1, ..., vj),其中 (vi, ..., v1) 是 vi 到 v1 的且中间顶点序号不大于 0 的最短路径,(v1, ..., vj) 是 v1 到 vj 的且中间顶点的序号不大于 0 的最短路径,这两条路径已在上一步中求出。比较 (vi, ...., v1, ..., vj) 与上一步求出的 vi 到 vj 的中间顶点序号不大于 0 的最短路径,取其中较短者作为 vi 到 vj 的中间顶点序号不大于 1 的最短路径。
-
依次类推,在 vi 和 vj 间加入顶点 vk,得到 (vi, ..., vk) 和 (vk, ..., vj),它们分别是从 vi 到 vk 和从 vk 到 vj 的中间顶点序号不大于 k - 1 的最短路径,将 (vi, ..., vk, ..., vj) 和已经得到的从 vi 到 vj 且中间顶点序号不大于 k - 1 的最短路径相比较,其长度较短者便是从 vi 到 vj 的中间顶点的序号不大于 k 的最短路径。这样,经过 n 次比较后,最后求得的必是从 vi 到 vj 的最短路径。按此方法,可用同时求得各对顶点间的最短路径。
void ShortestPath_Floyd(AMGraph* pg, int** D, int** Path)
{assert(pg);for (int i = 0; i < pg->vSize; ++i){for (int j = 0; j < pg->vSize; ++j){D[i][j] = pg->arcs[i][j];if (i != j && D[i][j] != INT_MAX)Path[i][j] = i;elsePath[i][j] = -1;}}
for (int k = 0; k < pg->vSize; ++k){for (int i = 0; i < pg->vSize; ++i){for (int j = 0; j < pg->vSize; ++j){if (i != k && j != k && i != j){if (D[i][k] != INT_MAX && D[k][j] != INT_MAX &&D[i][k] + D[k][j] < D[i][j]){D[i][j] = D[i][k] + D[k][j];Path[i][j] = Path[k][j];}}}}}
}
Test.c:
#include "AMGraph.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{AMGraph g;AMGraphInit(&g);InsertVertex(&g, 'A');InsertVertex(&g, 'B');InsertVertex(&g, 'C');InsertVertex(&g, 'D');InsertArc(&g, 'A', 'B', 1);InsertArc(&g, 'A', 'D', 4);InsertArc(&g, 'B', 'C', 9);InsertArc(&g, 'B', 'D', 2);InsertArc(&g, 'C', 'A', 3);InsertArc(&g, 'C', 'B', 5);InsertArc(&g, 'C', 'D', 8);InsertArc(&g, 'D', 'C', 6);ShowAdjMatrix(&g);printf("\n");
int** D = (int**)malloc(sizeof(int*) * g.vSize);assert(D);for (int i = 0; i < g.vSize; ++i){D[i] = (int*)malloc(sizeof(int) * g.vSize);assert(D[i]);}int** Path = (int**)malloc(sizeof(int*) * g.vSize);assert(Path);for (int i = 0; i < g.vSize; ++i){Path[i] = (int*)malloc(sizeof(int) * g.vSize);assert(Path[i]);}ShortestPath_Floyd(&g, D, Path);
for (int i = 0; i < g.vSize; ++i){for (int j = 0; j < g.vSize; ++j){printf("%d ", D[i][j]);}printf("\n");}printf("\n");for (int i = 0; i < g.vSize; ++i){for (int j = 0; j < g.vSize; ++j){printf("%d ", Path[i][j]);}printf("\n");}
free(D);free(Path);return 0;
}

相关文章:
【图的应用二:最短路径】- 用 C 语言实现迪杰斯特拉算法和弗洛伊德算法
目录 一、最短路径 二、迪杰斯特拉算法 三、弗洛伊德算法 一、最短路径 假若要在计算机上建立一个交通咨询系统,则可以采用图的结构来表示实际的交通网络。如下图所示,图中顶点表示城市,边表示城市间的交通联系。 这个咨询系统可以回答旅…...
Qt之判断一个点是否在多边形内部(射线法)
算法思想: 以被测点Q为端点,向任意方向作射线(一般水平向右作射线),统计该射线与多边形的交点数。如果为奇数,Q在多边形内;如果为偶数,Q在多边形外。计数的时候会有一些特殊情况。这种方法适用于任意多边形,不需要考虑精度误差和多边形点给出的顺序,时间复杂度为O(n)…...
压力测试过程中内存溢出(堆溢出、栈溢出、持久代溢出)情况如何解决
在压力测试过程中,可能会遇到内存溢出的问题,其中常见的包括堆内存溢出、栈内存溢出和持久代溢出。解决这类问题需要首先理解各种内存溢出的原因和特点。 堆内存溢出:这种情况通常发生在稳定性压测一段时间后,系统报错࿰…...
【工业智能】音频信号相关场景
【工业智能】音频信号相关场景 DcaseDcase introduction:dcase2024有10个主题的任务: ASD硬件设备产品商 方法制造业应用场景 zenodo音频事件检测 与计算机视觉CV相对应,计算机听觉computer audition,简称CA。 Dcase 这里推荐一个…...
(PC+WAP)装修设计公司网站模板 家装公司网站源码下载
(PCWAP)装修设计公司网站模板 家装公司网站源码下载 PbootCMS内核开发的网站模板,该模板适用于装修设计、家装公司类等企业,当然其他行业也可以做,只需要把文字图片换成其他行业的即可; PCWAP,同一个后台,…...
使用opencv实现图像中几何图形检测
1 几何图形检测介绍 1.1 轮廓(contours) 什么是轮廓,简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具,在OpenCV 中使用轮廓发现相关函数时候要求输入图像是二值图像,这…...
补题与周总结:leetcode第 376 场周赛
文章目录 复盘与一周总结2967. 使数组成为等数数组的最小代价(中位数贪心 回文数判断)2968. 执行操作使频率分数最大(中位数贪心 前缀和 滑窗) 复盘与一周总结 wa穿了第3题,赛时其实想到了思路:中位数贪心…...
js指纹库,可跟踪用户唯一性
fingerprintjs官网 资料: Browserleaks - Check your browser for privacy leaks...
Shell三剑客:awk(内部变量)
一、$0 :完整的输入记录 [rootlocalhost ~]# awk -F: {print $0} passwd.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/s…...
JVM中的虚拟机栈的动态链接部分存放到底是什么
在Java虚拟机(JVM)中,每个线程在执行一个方法时都会创建一个栈帧(Stack Frame),栈帧中包含了方法的运行时数据。栈帧通常包括局部变量表、操作数栈、动态链接、方法返回地址等部分。 动态链接 动态链接&a…...
Leetcode 55 跳跃游戏
题意理解: 非负整数数组 nums, 最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 需要跳到nums最后一个元素即为成功。 目标:是否能够跳到最后一个元素。 解题思路: 使用贪心算法来解题,需要理解…...
构建陪诊预约系统:技术实战指南
在医疗科技的飞速发展中,陪诊预约系统的应用为患者和陪诊人员提供了更为便捷和贴心的服务。本文将带领您通过技术实现,构建一个简单而实用的陪诊预约系统,以提升医疗服务的效率和用户体验。 技术栈选择 在开始之前,我们需要选择…...
windows和linux将文件删除至回收站【C++】【Go】语言实现
目录 C Windows平台 Linux平台 开平台,代码合并 Go 实现步骤 Go语言实现示例 go单独的windows版本实现 代码解释 C 在C中,将文件移动到回收站的实现在Linux和Windows平台上是不同的。首先,我会为你提供在Windows平台上实现的代码示例…...
10 Vue3中v-html指令的用法
概述 v-html主要是用来渲染富文本内容,比如评论信息,新闻信息,文章信息等。 v-html是一个特别不安全的指令,因为它会将文本以HTML的显示进行渲染,一旦文本里面包含一些恶意的js代码,可能会导致整个网页发…...
华为数通方向HCIP-DataCom H12-831题库(多选题:181-200)
第181题 如图所示,R1、R2、R3、R4都部署为SPF区域0,链路的cost值如图中标识。R1、R2R3、R4的Loopback0通告入OSPF。R1、R2、R3与R4使用Loopback0作为连接接口,建立BGP对等体关系,其中R4为RR设备,R1、R2、R3是R4的客户端。当R4的直连地址172.20,1,4/32通告入BGP后,以下关R…...
DC-磁盘管理
2023年全国网络系统管理赛项真题 模块B-Windows解析 题目 在DC2上安装及配置软RAID 5。在安装好的DC2虚拟机中添加三块10G虚拟磁盘。组成RAID 5,磁盘分区命名为卷标H盘:Raid5。手动测试破坏一块磁盘,做RAID磁盘修复,确认RAID 5配置完毕。配置步骤 关闭虚拟机,添加3块10G磁…...
使用Docker运行镜像文件与设置端口
1,创建镜像文件前准备 # 使用基础镜像FROM alpine:latest# 设置工作目录WORKDIR /app# 复制应用程序文件到镜像中COPY . .# 暴露容器的端口 不会自动将容器的端口映射到宿主机上 docker run -d -p <宿主机端口>:7080 <镜像名称>EXPOSE 7080# 定义容器启…...
Centos 8.5 Oracle12c安装
由于多次安装踩坑,所以本次写了一份12c安装的完整版。可以直接使用。 一、安装数据库基本信息 名称 值 主机名 database 操作系统 CentOS Linux release 8.5.2111 Oracle用户名/密码 oracle Oracle 版本 12c Enterprise Edition Release 12.2.0.1.0 oracle…...
Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现
Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 在Apache Tomcat中发现了一个被归类为关键的漏洞,该漏洞在8.5.4(Application Server Soft ware)以下。受影响的是组…...
ChatGLM3-6B 的调用参数说明,chat 与stream_chat 接口函数的参数说明
ChatGLM3-6B 是一个语言大模型,最近在评估这个模型,但发现它的文档有限,只能从demo代码中猜测调用的参数的含义,准确度是有限的;于是,通过查看源代码来研究,目前整理笔记如下: Chat…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
TJCTF 2025
还以为是天津的。这个比较容易,虽然绕了点弯,可还是把CP AK了,不过我会的别人也会,还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...
