图论

news/2025/3/19 21:59:52/文章来源:https://www.cnblogs.com/alohablogs/p/18155472

1 图论

1.1 图的建立

1.1.1 领接表边权建图

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class Main {// 定义图的邻接表表示static List<int[]>[] g;// 节点数static int n;// 保存某种状态或结果的数组static int[] f;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 读取节点数n = scanner.nextInt();// 初始化图的邻接表g = new ArrayList[n + 1];for (int i = 1; i <= n; i++) {g[i] = new ArrayList<>();}// 初始化状态数组f = new int[n + 1];// 读取边的信息并构建图for (int i = 1; i < n; i++) {int a = scanner.nextInt(); // 边的一个端点int b = scanner.nextInt(); // 边的另一个端点int c = scanner.nextInt(); // 边的权重// 添加无向边到邻接表g[a].add(new int[]{b, c});g[b].add(new int[]{a, c});}}// 深度优先搜索(DFS)遍历图static void dfs(int u, int fa) {// 遍历节点u的所有邻接节点for (int[] pair : g[u]) {int x = pair[0]; // 邻接节点int w = pair[1]; // 边的权重// 如果邻接节点是父节点,则跳过(避免走回头路)if (x == fa) continue;// 递归遍历邻接节点dfs(x, u);// 这里可以添加其他的逻辑处理代码}}
}

  

1.1.2 领接表点权建图

import java.util.Scanner;
import java.util.ArrayList;public class Main {// 定义常量N为节点数的上限static final int N = 100010;// 用于存储图的邻接表表示static ArrayList<Integer>[] g = new ArrayList[N];// 用于存储节点的权值static int[] w = new int[N];// 深度优先搜索(DFS)遍历图static void dfs(int u, int fa) {// 处理节点u的操作// 遍历节点u的所有邻接节点for (int x : g[u]) {// 如果邻接节点是父节点,则跳过(避免走回头路)if (x == fa)continue;// 递归遍历邻接节点dfs(x, u);// 处理子节点返回后的操作}}public static void main(String[] args) {int n, m;Scanner scanner = new Scanner(System.in);// 读取节点数n和边数mn = scanner.nextInt();m = scanner.nextInt();// 初始化邻接表for (int i = 1; i <= n; i++) {g[i] = new ArrayList<>();}// 读取边的信息并构建图for (int i = 0; i < m; i++) {int a, b;a = scanner.nextInt();b = scanner.nextInt();g[a].add(b);  // 添加一条从a到b的边}// 读取每个节点的权值for (int i = 1; i <= n; i++) {w[i] = scanner.nextInt();}// 可以在这里调用dfs进行深度优先搜索,例如从节点1开始// dfs(1, -1);}
}

  

1.1.3 离散化建图

  1. 点的范围很大(例如 [−109,109]),或者含有负数的点。
  2. 点不是数值,而是字符串,字符串与字符串之间存在相互转换的关系。
import java.util.*;public class Main {public static void main(String[] args) {// 定义一个常量N,表示可能的最大节点数int N = 100010;// 定义一个哈希表,用于存储节点之间的边及其权重// 键是节点,值是一个包含目标节点及边权的列表Map<Integer, List<Map.Entry<Integer, Integer>>> path = new HashMap<>();// 示例:添加从节点u到节点v,边的权重为wint u = 1, v = 2, w = 3;// 如果哈希表中不包含键u,初始化其值为一个新的ArrayListif (!path.containsKey(u)) {path.put(u, new ArrayList<>());}// 将边(v, w)添加到节点u的列表中path.get(u).add(new AbstractMap.SimpleEntry<>(v, w));// 示例:遍历节点node的所有相邻节点和边权int node = 1;// 如果哈希表中包含键node,进行遍历if (path.containsKey(node)) {for (Map.Entry<Integer, Integer> entry : path.get(node)) {int target = entry.getKey();  // 相邻节点int weight = entry.getValue(); // 边的权重// 进行处理,例如打印或其他逻辑System.out.println("从节点 " + node + " 到节点 " + target + " 的边权是 " + weight);}}}
}

  

1.2 拓扑排序

 用于判断有向图中是否存在环

LeetCode 207. 课程表

拓扑排序模板题
根据依赖关系建图:先学习课程a必须要先学习课程b,则有b->a这一条有向边。如果可以完成所有课程,则说明存在拓扑排序。
 
import java.util.*;class Solution {public boolean canFinish(int numCourses, int[][] prerequisites) {// 创建图的邻接表表示List<List<Integer>> g = new ArrayList<>();for (int i = 0; i < numCourses; i++) {g.add(new ArrayList<>()); // 为每个节点初始化邻接表}// 创建数组存储每个节点的入度int[] d = new int[numCourses];// 构建图并计算每个节点的入度for (int[] p : prerequisites) {g.get(p[1]).add(p[0]); // 添加从节点p[1]到节点p[0]的边d[p[0]]++; // 增加节点p[0]的入度}// 初始化队列用于BFSQueue<Integer> q = new LinkedList<>();int cnt = 0; // 计数器,记录可以遍历的节点数量// 将所有入度为0的节点添加到队列中for (int i = 0; i < numCourses; i++) {if (d[i] == 0) {q.offer(i);cnt++;}}// 执行BFS处理节点while (!q.isEmpty()) {int t = q.poll(); // 从队列中取出一个节点for (int v : g.get(t)) { // 遍历所有依赖于t的节点d[v]--; // 减少依赖节点的入度if (d[v] == 0) { // 如果依赖节点的入度变为0,将其加入队列q.offer(v);cnt++;}}}// 如果处理的节点数量等于总节点数,则表示可以遍历所有节点,否则不能return cnt == numCourses;}
}

 

华为实习2023042601

开发一个新的3D引擎,包含多个模块,每个模块负责不同的功能,比如渲染、物理、音效、网络等。 为了提高性能和稳定性,需要在游戏启动时初始化这些模块。
但是不同的模块之间存在依赖关系,比如渲染模块依赖于物理模块,音效模块依赖于网络模块等。如果不按照正确的顺序初始化这些模块,就会导致错误或崩溃。
需要开发一个代码分析工具,分析代码模块之间的依赖关系,确定模块的初始化顺序,判断是否有循环依赖等问题。 工具可以一次初始化一个或多个模块,只要它们之间没有依赖关系。
这个过程称为引擎模块初始化。 已经得到了一组模块间的依赖关系,需要计算引擎模块初始化的次数。

 

输入描述

  • 第一行是一个整数 `n`,表示模块总数。
  • 接下来的 `n` 行表示模块 `1` 到 `n` 的依赖关系。
  • 每行的第一个数是一个整数 `m`,表示依赖的模块数量,之后的数字表示当前模块依赖的模块ID。
  • 每一行的数字按空格分隔。

约束条件:

  • 1 ≤ m ≤ n ≤ 1000

输出描述

  • 输出批量初始化次数。
  • 若有循环依赖无法完成初始化,则输出 `-1`

样例

样例一

输入

5
3 2 3 4
1 5
1 5
1 5
0

  输出

3

解释

共 5 个模块。

模块 `1` 依赖模块 `2`、`3`、`4`;

模块 `2` 依赖模块 `5`;

模块 `3` 依赖模块 `5`;

模块 `4` 依赖模块 `5`;

模块 `5` 没有依赖。

批量初始化顺序为 `{5} -> {2, 3, 4} -> {1}`,共需 3 次批量初始化。

 

代码 

import java.util.*;public class Main {public void solution(){Scanner scanner = new Scanner(System.in);int n = scanner.nextInt(); // 读取模块总数int[] inDegree = new int[n + 1]; // 入度数组,用于记录每个模块的依赖计数inDegree[0] = -1; // 虚拟的0号节点,设置为-1ArrayList<Integer>[] outDegree = new ArrayList[n + 1]; // 出度表,用于记录每个模块的被依赖关系// 读取每个模块的依赖信息for(int i = 1; i <= n; ++i){int m = scanner.nextInt(); // 读取当前模块的依赖数量inDegree[i] += m; // 更新入度for(int j = 0; j < m; ++j){int from = scanner.nextInt(); // 读取依赖的模块IDif(outDegree[from] == null)outDegree[from] = new ArrayList<>();outDegree[from].add(i); // 将当前模块添加到依赖列表中}}scanner.close(); int res = 0; // 记录批量初始化次数boolean check; // 用于判断当前批次是否有可初始化的模块Queue<Integer> queue = new LinkedList<>(); // 队列用于BFS// 执行拓扑排序do {check = false;// 找出所有入度为0的模块for(int i = 1; i < inDegree.length; ++i){if(inDegree[i] == 0){inDegree[i] = -1; // 标记为已处理check = true;queue.offer(i); // 将模块加入队列}}if(check)res += 1; // 增加批次计数// 处理队列中的模块while(!queue.isEmpty()){int from = queue.poll(); // 取出队首模块if(outDegree[from] == null)continue;// 减少依赖模块的入度for(int i = 0; i < outDegree[from].size(); ++i)--inDegree[outDegree[from].get(i)];}}while(check);// 检查是否存在未处理的模块for(int i = 1; i < inDegree.length; ++i){if(inDegree[i] != -1){System.out.println(-1); // 存在循环依赖,输出-1return;}}System.out.println(res); // 输出批量初始化次数}public static void main(String[] args) {Main m = new Main();m.solution(); // 调用解决方案}
}

 

华为秋招20230830

系统由n个任务组成,任务运行有依赖关系,前序任务执行完毕才可以启动后续任务。任务在启动前申请内存,执行完毕后释放,内存释放后可用于其他任务使用。

解除依赖后的任务会直接由操作系统调度,分配内存,进入运行状态。每个任务的运行时间相等。请计算系统所有任务执行所需要的最小内存。  

输入

1行为1个正整数n,表示任务个数,n<20

2行为n个正整数,表示每个任务所需要的内存大小,0<内存<10000

3行为n个取值为0或1的数,表示任务0对其他任务的依赖关系,0表示不依赖,1表示依赖

....

3+n行为n个取值为01的数,表示任务n1对其他任务的依赖关系,0表示不依赖,1表示依赖

输出

输出系统任务执行所需要的最小内存

样例

输入

9
50 50 80 40 40 40 60 60 60
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 1 0 0 1 0 0 0
0 0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 1 0

输出

120

解释

样例解释

第一行:9,表示有 9 个任务

第二行:50 50 80 40 40 40 60 60 60,表示每个任务所需要的内存大小

  • t0 需要 50
  • t1 需要 50
  • t2 需要 80
  • t3 需要 40
  • t4 需要 40
  • t5 需要 40
  • t6 需要 60
  • t7 需要 60
  • t8 需要 60

第三行:0 0 0 0 0 0 0 0 0,表示 t0 不依赖任何任务

第四行:1 0 0 0 0 0 0 0 0,表示 t1 依赖 t0

第五行:0 1 0 0 0 0 0 0 0,表示 t2 依赖 t1

...依此类推

任务的关系用图表示:

 

  • 执行 t0,分配 m0 = 50,占用空间 [0, 50),最大访问地址为 50
  • 执行 t1,分配 m1 = 50,占用空间 [0, 50),最大访问地址为 50
  • 并发执行 t2t5,分配 m2 = 80m5 = 40,占用空间 [0, 120),最大访问地址为 120
  • 执行 t3,分配 m3 = 40,占用空间 [0, 40),最大访问地址为 40
  • 并发执行 t4t7,分配 m4 = 40m7 = 60,占用空间 [0, 100),最大访问地址为 100
  • 执行 t6,分配 m6 = 60,占用空间 [0, 60),最大访问地址为 60
  • 执行 t8,分配 m8 = 60,占用空间 [0, 60),最大访问地址为 60

输出系统需要的最小内存为 120

 

思路:拓扑排序+贪心

通过拓扑排序,我们可以确保每个任务按其依赖关系的顺序执行。每一轮计算并行执行的任务所需的总内存,并取这些总内存的最大值作为最终答案。这个方法能有效地解决问题并保证计算出的内存需求最小化。

 

import java.util.*;public class Main {// 定义常量和变量static final int M = 20;  // 最大任务数量static int[] in = new int[M];  // 记录每个任务的入度static int[] a = new int[M];   // 记录每个任务所需的内存public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();  // 读取任务数ArrayList<Integer>[] e = new ArrayList[M];  // 邻接表,存储依赖关系// 读取每个任务的内存需求并初始化邻接表for (int i = 1; i <= n; i++) {a[i] = scanner.nextInt();e[i] = new ArrayList<>();}// 读取依赖关系矩阵并构建图for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {int t = scanner.nextInt();if (t != 0) {in[i]++;  // 增加任务i的入度e[j].add(i);  // 添加一条从j到i的边}}}// 初始化队列,用于拓扑排序Queue<Integer> q = new LinkedList<>();Queue<Integer> tmp = new LinkedList<>();  // 临时队列,用于保存本轮入度为0的任务for (int i = 1; i <= n; i++) {if (in[i] == 0) {q.add(i);  // 将初始入度为0的任务加入队列}}int ans = 0;  // 保存最终的最小内存需求// 开始拓扑排序while (!q.isEmpty()) {int sum = 0;  // 记录当前轮次所有任务的内存总和while (!q.isEmpty()) {int u = q.poll();sum += a[u];  // 累加当前任务的内存需求// 遍历当前任务的所有后继任务for (int i = 0; i < e[u].size(); i++) {int v = e[u].get(i);in[v]--;  // 将后继任务的入度减1if (in[v] == 0) {tmp.add(v);  // 如果后继任务的入度为0,加入临时队列}}}ans = Math.max(ans, sum);  // 更新最大内存需求q.addAll(tmp);  // 将临时队列中的任务加入主队列,进行下一轮处理tmp.clear();  // 清空临时队列}// 输出最终计算出的最小内存需求System.out.println(ans);}
}

 

1.3 Dijkstra

求解从某个起点到达图上任意一点的最短路径(BFS 只能求解边权值为1)
import java.util.*;
import java.io.*;class Main {static int N = 100010;  // 定义常量,最大点数static int n, m, idx;  // n为点数,m为边数,idx为边的编号static int[] h = new int[N];  // h数组,邻接表头结点static int[] w = new int[N];  // w数组,边权重static int[] e = new int[N];  // e数组,边指向的节点static int[] ne = new int[N];  // ne数组,邻接表下一个节点static int[] dist = new int[N];  // dist数组,记录1号点到各点的最短距离static boolean[] st = new boolean[N];  // st数组,记录每个点是否已确定最短路// 添加边的函数private static void add(int a, int b, int c) {e[idx] = b;  // 边的终点w[idx] = c;  // 边的权重ne[idx] = h[a];  // 当前边的下一个边h[a] = idx++;  // 更新头结点}public static void main(String[] args) throws Exception {// 使用BufferedReader和BufferedWriter进行输入输出BufferedReader br = new BufferedReader(new InputStreamReader(System.in));BufferedWriter log = new BufferedWriter(new OutputStreamWriter(System.out));// 读取第一个输入行String[] values = br.readLine().split("\\s+");n = Integer.parseInt(values[0]);m = Integer.parseInt(values[1]);// 初始化邻接表头结点Arrays.fill(h, -1);// 读取所有边的信息while (m-- > 0) {values = br.readLine().split("\\s+");int a = Integer.parseInt(values[0]);int b = Integer.parseInt(values[1]);int c = Integer.parseInt(values[2]);add(a, b, c);}// 计算1号点到n号点的最短路径int ret = dijkstra(n);// 输出结果log.write(ret + "\n");log.flush();log.close();br.close();}// 堆优化的Dijkstra算法private static int dijkstra(int n) {// 优先队列,按照到达节点的最短距离排序PriorityQueue<int[]> pq = new PriorityQueue<>(n, (a, b) -> a[1] - b[1]);int INF = 1 << 30;  // 定义一个无限大值Arrays.fill(dist, INF);  // 初始化距离数组,全部设为无穷大pq.offer(new int[]{1, 0});  // 将起点1加入优先队列dist[1] = 0;  // 起点到自己的距离为0// 主循环while (!pq.isEmpty()) {int[] cur = pq.poll();int ver = cur[0];  // 当前处理的节点int distance = cur[1];  // 当前节点的最短距离// 如果该节点已被处理,则跳过if (st[ver]) continue;st[ver] = true;  // 标记该节点为已处理// 遍历当前节点的所有邻边for (int i = h[ver]; i != -1; i = ne[i]) {int j = e[i];  // 目标节点// 如果找到更短的路径,则更新if (dist[j] > distance + w[i]) {dist[j] = distance + w[i];pq.offer(new int[]{j, dist[j]});  // 将更新后的节点加入优先队列}}}// 如果n号点的最短路径仍为无穷大,说明不可达return dist[n] == INF ? -1 : dist[n];}
}

  

 

华为2023082303

有一些镜子,能够吸收光芒并在一定时间后散射。

镜子分为一级镜和二级镜,一级镜散射速度为1ms,二级镜为2ms。

将镜子放在一个二维矩阵中,每个镜子的坐标为整数。

现在给某个镜子一道光芒,最早什么时候所有镜子都能吸收到光芒?

注:矩阵的下标从0开始。

 

输入描述:

 

矩阵的列数  n ( n≤500 )

矩阵的行数  m  ( m ≤ 500 )

最初获得光芒的镜子的坐标  (i, j) 

接下来  m  行,每行  n  个数字,代表该位置镜子的等级:

  • 0 表示该位置是一堵密不透光的墙
  • 1 表示该位置的镜子散射耗时1ms
  • 2 表示该位置的镜子散射耗时2ms

 

输出描述:

一个数字代表最小时间。如果有镜子不能够吸收到光芒,输出-1。

 

样例:

输入:

552 21 0 2 1 02 2 1 2 00 0 1 0 02 1 1 0 01 1 1 1 1

  

输出:

6

 

思路:

找到所有镜子接收到光芒的最早时间=>单源最短路算法:Dijkstra:

  1. 每一步,从队列中取出时间最早的镜子。
  2. 更新其四个方向镜子的接收时间。
  3. 如果新的接收时间比当前的接收时间早,则更新接收时间,并将新的镜子加入队列。
import java.util.*;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 读取输入,直到没有更多的整数输入while (in.hasNextInt()) {int n = in.nextInt(); // 矩阵的行数int m = in.nextInt(); // 矩阵的列数int[][] mirrors = new int[n][m]; // 存储镜子等级的矩阵int initI = in.nextInt(); // 初始光芒镜子的行坐标int initJ = in.nextInt(); // 初始光芒镜子的列坐标// 读取矩阵中的镜子等级for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {mirrors[i][j] = in.nextInt();}}int[][] times = new int[n][m]; // 存储每个镜子接收到光芒的时间// 初始化时间矩阵,初始值设为一个较大的数for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {times[i][j] = Integer.MAX_VALUE;}}// 优先队列,用于进行Dijkstra算法Queue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {return o1[2] - o2[2]; // 按时间排序}});int[][] visited = new int[n][m]; // 标记每个镜子是否已经接收到光芒queue.offer(new int[]{initI, initJ, 0}); // 将初始镜子加入队列,时间设为0// Dijkstra算法while (!queue.isEmpty()) {int[] poll = queue.poll(); // 取出时间最早的镜子int x = poll[0];int y = poll[1];int time = poll[2];// 边界条件检查if (x < 0 || x >= mirrors.length || y < 0 || y >= mirrors[0].length) {continue;}// 如果是墙则跳过if (mirrors[x][y] == 0) {continue;}// 如果已经访问过则跳过if (visited[x][y] == 1) {continue;}visited[x][y] = 1; // 标记为已访问times[x][y] = time; // 更新当前镜子的时间// 将四个方向的镜子加入队列,并更新时间queue.offer(new int[]{x - 1, y, time + mirrors[x][y]});queue.offer(new int[]{x + 1, y, time + mirrors[x][y]});queue.offer(new int[]{x, y - 1, time + mirrors[x][y]});queue.offer(new int[]{x, y + 1, time + mirrors[x][y]});}int max = 0; // 用于找出接收到光芒的最晚时间for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {// 只考虑不是墙的镜子if (mirrors[i][j] != 0) {max = Math.max(max, times[i][j]);}}}// 如果有镜子不能接收到光芒,则返回-1if (max == Integer.MAX_VALUE) {System.out.println(-1);} else {System.out.println(max); // 输出最早时间}}}
}

 

饿了么2023081703

有一个迷宫,有 `n` 个地点,通过 `m` 条道路联通。每次需要从起点(1号节点)取一面旗帜送到指定地点,然后返回起点,直到将所有旗帜送完。

你需要知道送完所有旗帜的最短路程是多少。

输入描述

  1. 第一行输入三个整数 `n`, `m`, `q`,分别表示地点数、路径数和需要送达旗帜的地点数。
  2. 接下来 `m` 行,每行输入三个整数 `u`, `v`, `w`,表示地点 `u` 和地点 `v` 之间有一条长度为 `w` 的道路。
  3. 最后一行输入 `q` 个整数,表示需要送达旗帜的 `q` 个地点。

输出描述
一个整数表示最短总路程。

示例
输入

4 3 3
1 2 1
2 3 2
3 4 3
2 3 4

  

 输出

20

说明
从 1 号点到 2 号点再回来,路程距离为 2。
再从 1 号点到 3 号点再回来,路程距离为 6。
最后从 1 号点到 4 号点再回来,路程距离为 12。

 思路:

利用Dijkstra,初始化从起点到其余n-1个节点最短路径dist,最后遍历并累加 dist[qi]*2即可。

import java.util.*;public class Main {public static void main(String[] args) {final int INF = 0x3f3f3f3f;Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int T = scanner.nextInt();List<List<PII>> g = new ArrayList<>();for (int i = 0; i < n; i++) {g.add(new ArrayList<>());}for (int i = 0; i < m; i++) {int u = scanner.nextInt() - 1;int v = scanner.nextInt() - 1;int w = scanner.nextInt();g.get(u).add(new PII(v, w));g.get(v).add(new PII(u, w));}PriorityQueue<PII> q = new PriorityQueue<>(Comparator.comparingInt(PII::getFirst));int[] st = new int[n];int[] dist = new int[n];Arrays.fill(dist, INF);dist[0] = 0;q.offer(new PII(0, 0));while (!q.isEmpty()) {PII top = q.poll();int u = top.getSecond();if (st[u] == 1) continue;st[u] = 1;for (PII p : g.get(u)) {int v = p.getFirst();int w = p.getSecond();if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;q.offer(new PII(dist[v], v));}}}long ans = 0;while (T-- > 0) {int x = scanner.nextInt() - 1;ans += dist[x];}System.out.println(ans * 2);}static class PII {private final int first;private final int second;public PII(int first, int second) {this.first = first;this.second = second;}public int getFirst() {return first;}public int getSecond() {return second;}}
}

  

  

  

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/720020.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IO

IO电路其实就是指芯片的信号输入输出接口电路,其一般位于芯片版图的最外围。IO电路一般有以下几个功能: (1)实现电平转换 (2)提高驱动能力 (3)进行ESD保护 先说电平转换。芯片内部电路信号的高低电平和外部要求不一致时,这样通过IO电路可以实现电平的转换。 再说驱动能…

Level shifter

(M1由关断到开启,肯定是先进入饱和区,因为这个临界点时,M1的Vds=VDDH>Vgs-Vth1=VDDL-Vth1,肯定是饱和区) M1的饱和区电流肯定先是大于M3的线性区电流,使得N点持续由VDDH放电到地,这个过程不能使得M1电流小于M3电流,否则N点下拉失败,OUT无法输出高电平VDDH。也就是…

从上下文切换谈thread_local工作原理

介绍thread_local的实现原理从上下文切换谈thread_local工作原理 thread_local是什么 熟悉多线程编程的小伙伴一定对thread_local不陌生,thread_local 是 C++11 引入的一种存储类说明符,用于定义每个线程都有其独立实例的变量。每个线程对这些变量有自己的副本,而不共享其他…

POR

上电复位(POR)电路,其作用是保证在施加电源后,模拟和数字模块初始化至已知状态。基本上电复位(POR)功能会产生一个内部复位脉冲以避免"竞争"现象,并使器件保持静态,直至电源电压达到一个能保证正常工作的阈值。注意,此阈值电压不同于数据手册中给出的最小电…

C++U7-07-图的遍历进阶

学习目标 引例 深搜遍历 [【图的遍历进阶】有向图中的可达]【算法分析】 从 a 点广搜,并用 vis 数组标记从 a 能够到达的点,如果 vis b ​=true,则表示能够到达,否则反之。【参考代码】 #include<bits/stdc++.h> using namespace std; const int maxn = 2e5 + …

第2次总结性Blog-题目集4~6

目录前言 设计与分析 采坑心得 改进建议 总结关于java&面向对象在经过这几个月的系统性的java学习中,我始终牢记着一句话:面对对象程序设计最重要的是设计,而不是代码。设计即要遵守单一职责原则,简单来说就是什么该做,什么不该做。设计的越好,复用性就越高,需要修改…

一款WPF的精简版MVVM框架——stylet框架的初体验(包括MVVM绑定、依赖注入等操作)

今天偶然知道一款叫做stylet的MVVM框架,挺小巧的,特别是它的命令触发方式,简单粗暴,让人感觉很巴适,现在我做一个简单的demo来顺便来分享给大家。 本地创建一个WPF项目,此处我使用.NET 8来创建。然后引用stylet最新的nuget包。 然后删掉App.xaml里面自带的启动项删掉以后…

按键中断驱动程序-poll机制

前言:学东西的时候总是喜欢碎碎念,去思考该怎么学。关于嵌入式开发,以前就觉得嵌入式只是一个工具,关键还是结合专业知识赋能,比如控制、信号处理、神经网络、计算机网络、各种协议比如蓝牙、wifi,音视频,当然,如果能够把内核学的很透彻,那也是很了不起的。现在越学越…

UDP协议的应用——域名解析

设计程序实现解析www.baidu.com 的域名,把获取到的百度的IP地址全部输出到终端并验证是否正确设计程序实现解析www.baidu.com 的域名,把获取到的百度的IP地址全部输出到终端并验证是否正确 /******************************************************************************…

基于腾讯元器搭建前端小助手

通过本文,我们了解了如何利用腾讯元器搭建一个前端助手智能体。通过使用插件和观察其使用效果,我们可以发现前端助手在解决问题和提供帮助方面的潜力。这个前端助手可以成为我们在前端开发过程中的得力助手,帮助我们提高工作效率和解决难题。随着智能技术的不断进步,我们可…