文心一言 VS 讯飞星火 VS chatgpt (299)-- 算法导论22.1 3题

三、有向图 G = ( V , E ) G=(V,E) G=(V,E) 的转置是图 G T = ( V , E T ) G^{T} =(V,E^{T}) GT=(V,ET),这里 E T = { ( v , u ) ∈ V × V E^{T} =\{(v,u)∈ V \times V ET={(v,u)V×V:(u,v)∈ E}$因此,图 G T G^{T} GT 就是将有向图 G G G中所有边的方向反过来而形成的图。对于邻接链表和邻接矩阵两种表示,请给出从图 G G G计算出 G T G^{T} GT的有效算法,并分析算法的运行时间。如果要写代码,请用go语言。

文心一言:

为了从有向图 G G G 计算出其转置图 G T G^T GT,我们可以分别针对邻接链表和邻接矩阵两种表示形式来设计算法。下面我将分别给出这两种方法的描述以及相应的 Go 语言代码实现。

1. 邻接链表表示

在邻接链表中,每个节点维护一个链表,链表中的每个节点表示从当前节点出发可以到达的节点。为了得到转置图,我们需要遍历原图的所有边,并将每条边的方向反转,即对于边 ( u , v ) (u, v) (u,v),我们在 G T G^T GT 中添加边 ( v , u ) (v, u) (v,u)

算法步骤

  1. 初始化 G T G^T GT 的邻接链表表示。
  2. 遍历 G G G 的每一条边 ( u , v ) (u, v) (u,v)
  3. G T G^T GT 中,将 v v v 添加到 u u u 的链表中(如果 u u u 的链表不存在,则先创建)。

Go 代码实现

package mainimport "fmt"type Graph struct {adjList map[int][]int
}func NewGraph() *Graph {return &Graph{adjList: make(map[int][]int)}
}func (g *Graph) AddEdge(from, to int) {g.adjList[from] = append(g.adjList[from], to)
}func (g *Graph) Transpose() *Graph {transposed := NewGraph()for from, tos := range g.adjList {for _, to := range tos {transposed.AddEdge(to, from)}}return transposed
}func main() {g := NewGraph()g.AddEdge(0, 1)g.AddEdge(0, 2)g.AddEdge(1, 2)g.AddEdge(2, 0)gt := g.Transpose()fmt.Println("Transposed Graph:")for from, tos := range gt.adjList {fmt.Printf("%d -> %v\n", from, tos)}
}

时间复杂度 O ( V + E ) O(V+E) O(V+E),其中 V V V 是节点数, E E E 是边数。因为我们需要遍历每条边并可能更新每个节点的链表。

2. 邻接矩阵表示

在邻接矩阵中,矩阵的每个元素 A [ i ] [ j ] A[i][j] A[i][j] 表示从节点 i i i 到节点 j j j 是否存在边。为了得到转置图,我们只需将矩阵转置即可。

算法步骤

  1. 初始化 G T G^T GT 的邻接矩阵,大小与 G G G 相同。
  2. 遍历 G G G 的邻接矩阵的每一个元素 A [ i ] [ j ] A[i][j] A[i][j]
  3. 如果 A [ i ] [ j ] A[i][j] A[i][j] 非零(或根据图的类型,可能有其他表示方式),则将 G T G^T GT 的邻接矩阵中 A T [ j ] [ i ] A^T[j][i] AT[j][i] 设置为相同的值。

Go 代码实现

package mainimport "fmt"type MatrixGraph struct {matrix [][]intsize   int
}func NewMatrixGraph(size int) *MatrixGraph {return &MatrixGraph{matrix: make([][]int, size), size: size}
}func (mg *MatrixGraph) AddEdge(from, to int) {mg.matrix[from][to] = 1
}func (mg *MatrixGraph) Transpose() *MatrixGraph {transposed := NewMatrixGraph(mg.size)for i := 0; i < mg.size; i++ {for j := 0; j < mg.size; j++ {transposed.matrix[j][i] = mg.matrix[i][j]}}return transposed
}func main() {mg := NewMatrixGraph(3)mg.AddEdge(0, 1)mg.AddEdge(0, 2)mg.AddEdge(1, 2)mg.AddEdge(2, 0)mgt := mg.Transpose()fmt.Println("Transposed Matrix Graph:")for _, row := range mgt.matrix {fmt.Println(row)}
}

**

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

讯飞星火:

首先,我们来分析邻接链表和邻接矩阵两种表示方法。

  1. 邻接链表表示法:
    在邻接链表中,每个顶点都有一个链表,链表中的每个元素表示与该顶点相邻的顶点。为了计算转置图 G T G^T GT,我们需要遍历原图 G G G的所有顶点,然后遍历每个顶点的链表,将链表中的顶点添加到新链表中,表示转置后的边。

  2. 邻接矩阵表示法:
    在邻接矩阵中,矩阵的每个元素表示两个顶点之间是否存在边。为了计算转置图 G T G^T GT,我们需要将原矩阵进行转置操作,即将矩阵的行和列互换。

接下来,我们给出两种表示法的算法实现:

  1. 邻接链表表示法:
func transposeGraph(graph []map[int]struct{}) map[int]map[int]struct{} {transposedGraph := make(map[int]map[int]struct{})for u, neighbors := range graph {transposedNeighbors := make(map[int]struct{})for v := range neighbors {transposedNeighbors[v] = struct{}{}}transposedGraph[u] = transposedNeighbors}return transposedGraph
}
  1. 邻接矩阵表示法:
func transposeMatrix(matrix [][]bool) [][]bool {rows := len(matrix)cols := len(matrix[0])transposedMatrix := make([][]bool, cols)for i := range transposedMatrix {transposedMatrix[i] = make([]bool, rows)for j := range transposedMatrix[i] {transposedMatrix[i][j] = matrix[j][i]}}return transposedMatrix
}

运行时间分析:

  1. 邻接链表表示法的时间复杂度为O(E),其中E为原图中的边数。因为我们需要遍历所有顶点的链表。
  2. 邻接矩阵表示法的时间复杂度为O(V^2),其中V为原图中的顶点数。因为我们需要遍历整个矩阵并进行转置操作。

360智脑:

邻接链表表示法

在邻接链表表示法中,我们可以直接遍历原图 G G G的每个节点的邻接链表,然后将每条边的方向反转后添加到新图 G T G^{T} GT的对应节点上。以下是用Go语言实现的代码:

type Graph struct {Vertices []*Node
}type Node struct {Value intAdjacent []*Node
}func (g *Graph) Transpose() *Graph {transposed := &Graph{make([]*Node, len(g.Vertices))}for i, node := range g.Vertices {transposed.Vertices[i] = &Node{node.Value, make([]*Node, 0)}}for _, node := range g.Vertices {for _, neighbor := range node.Adjacent {// Add edge from neighbor to current node in the transposed graphtransposed.Vertices[neighbor.Value].Adjacent = append(transposed.Vertices[neighbor.Value].Adjacent, node)}}return transposed
}

该算法的运行时间是 O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|) O(V+E),其中 ∣ V ∣ |V| V是图中顶点的数量, ∣ E ∣ |E| E是图中边的数量。这是因为我们需要遍历每个节点和每条边一次。

邻接矩阵表示法

在邻接矩阵表示法中,我们可以通过交换矩阵的行和列来得到转置图。以下是用Go语言实现的代码:

type MatrixGraph struct {Matrix [][]bool
}func (m *MatrixGraph) Transpose() *MatrixGraph {n := len(m.Matrix)transposed := make([][]bool, n)for i := range transposed {transposed[i] = make([]bool, n)}for i := 0; i < n; i++ {for j := 0; j < n; j++ {transposed[j][i] = m.Matrix[i][j]}}return &MatrixGraph{transposed}
}

该算法的运行时间是 O ( ∣ V ∣ 2 ) O(|V|^2) O(V2),因为在最坏的情况下,我们需要访问矩阵中的每个元素。如果图是稠密的(即 ∣ E ∣ ≈ ∣ V ∣ 2 |E| \approx |V|^2 EV2),那么这个算法的时间复杂度与邻接链表表示法的算法相当。但如果图是稀疏的(即 ∣ E ∣ < < ∣ V ∣ 2 |E| << |V|^2 E<<V2),那么邻接链表表示法的算法会更高效。

智谱清言:

在图的邻接链表表示中,每个顶点对应一个链表,链表中包含所有与该顶点相邻的顶点的信息。在邻接矩阵表示中,矩阵的行和列代表图的顶点,矩阵中的元素表示相应顶点之间的边。转置图意味着我们需要交换原图中边的方向。
下面分别给出使用邻接链表和邻接矩阵表示的有向图转置的算法,并使用Go语言实现。

邻接链表表示

算法

  1. 创建一个新的顶点列表,复制原图的顶点。
  2. 遍历原图的每个顶点。
  3. 对于每个顶点,遍历它的邻接表。
  4. 对于邻接表中的每条边 (u, v),在转置图中添加边 (v, u)
    运行时间:O(V + 2E),其中 V 是顶点数,E 是边数。遍历所有顶点一次,每个顶点处理它的邻接表,每条边被处理两次(一次在原图中,一次在转置图中)。
    Go 代码实现
package main
import ("fmt"
)
type Edge struct {To int
}
type Graph struct {Vertices []intEdges    []*Edge
}
func (g *Graph) AddEdge(from, to int) {g.Edges = append(g.Edges, &Edge{To: to})
}
func TransposeGraph(g *Graph) *Graph {transposed := &Graph{Vertices: make([]int, len(g.Vertices))}for _, v := range g.Vertices {transposed.AddEdge(v, g.Vertices...)}return transposed
}
func main() {g := &Graph{Vertices: []int{0, 1, 2, 3},Edges:    []*Edge{},}g.AddEdge(0, 1)g.AddEdge(0, 2)g.AddEdge(1, 2)g.AddEdge(2, 3)transposed := TransposeGraph(g)fmt.Println("Transposed Graph Edges:")for _, edge := range transposed.Edges {fmt.Printf("(%d, %d)\n", edge.To, edge.From)}
}

邻接矩阵表示

算法

  1. 创建一个新的顶点列表,复制原图的顶点。
  2. 遍历原图的邻接矩阵。
  3. 对于矩阵中的每个元素,如果 A[u][v] 为 1(表示存在从 u 到 v 的边),在转置图中设置 A[v][u] 为 1。
    运行时间:O(V^2),其中 V 是顶点数。遍历整个邻接矩阵。
    Go 代码实现
package main
import ("fmt"
)
func TransposeGraph(A [][]int) [][]int {V := len(A)transposed := make([][]int, V)for i := range transposed {transposed[i] = make([]int, V)}for i := 0; i < V; i++ {for j := 0; j < V; j++ {if A[i][j] == 1 {transposed[j][i] = 1}}}return transposed
}
func main() {A := [][]int{{0, 1, 1},{1, 0, 1},{1, 1, 0},}transposed := TransposeGraph(A)fmt.Println("Transposed Graph:")for _, row := range transposed {fmt.Println(row)}
}

上述代码展示了如何使用 Go 语言实现有向图的转置,

天工:

为了计算有向图 G G G 的转置 G T G^{T} GT,我们可以分别针对邻接链表和邻接矩阵两种表示方式设计算法。

邻接链表表示

算法描述
  1. 遍历图 G G G 的邻接链表。
  2. 对于每条边 ( u , v ) (u, v) (u,v),将其添加到 G T G^{T} GT 的邻接链表中,但方向相反,即作为顶点 v v v 的邻接边。
  3. 重复步骤2直到所有边都被处理。
运行时间分析

假设图 G G G n n n 个顶点和 m m m 条边,那么这个算法的时间复杂度是 O ( n + m ) O(n + m) O(n+m),因为我们需要遍历所有的边一次。空间复杂度也是 O ( n + m ) O(n + m) O(n+m),因为我们创建了一个新的邻接链表来存储转置图。

Go语言实现
type Graph struct {vertices []*Vertex
}type Vertex struct {id       intadjacent []*Vertex
}func transposeGraph(g *Graph) *Graph {t := &Graph{make([]*Vertex, len(g.vertices))}for i, v := range g.vertices {t.vertices[i] = &Vertex{id: v.id}}for _, v := range g.vertices {for _, neighbor := range v.adjacent {t.vertices[neighbor.id].adjacent = append(t.vertices[neighbor.id].adjacent, t.vertices[v.id])}}return t
}

邻接矩阵表示

算法描述
  1. 遍历图 G G G 的邻接矩阵。
  2. 对于每个元素 ( i , j ) (i, j) (i,j),如果 G [ i ] [ j ] G[i][j] G[i][j] 为真(表示有一条从 i i i j j j 的边),则在 G T G^{T} GT 的邻接矩阵中设置 G T [ j ] [ i ] G^{T}[j][i] GT[j][i] 为真。
  3. 重复步骤2直到所有元素都被处理。
运行时间分析

这个算法的时间复杂度是 O ( n 2 ) O(n^2) O(n2),其中 n n n 是顶点的数量,因为我们需要遍历整个邻接矩阵。空间复杂度也是 O ( n 2 ) O(n^2) O(n2),因为我们创建了一个新的邻接矩阵来存储转置图。

Go语言实现
type MatrixGraph struct {matrix [][]bool
}func transposeMatrixGraph(g *MatrixGraph) *MatrixGraph {n := len(g.matrix)t := &MatrixGraph{make([][]bool, n)}for i := range t.matrix {t.matrix[i] = make([]bool, n)}for i := 0; i < n; i++ {for j := 0; j < n; j++ {if g.matrix[i][j] {t.matrix[j][i] = true}}}return t
}

在这两个实现中,我们都创建了一个新的图或矩阵来存储转置图的结果。如果我们不想使用额外的空间,我们可以考虑在原始图或矩阵上直接修改,但这可能会影响到原始数据的完整性。

灵小智:

对于邻接链表表示的有向图 G = ( V , E ) G=(V,E) G=(V,E),可以按照以下步骤计算出转置图 G T = ( V , E T ) G^T=(V,E^T) GT=(V,ET)的邻接链表表示:

  1. 初始化一个新的空邻接链表表示的转置图 G T G^T GT

  2. 对于有向图 G G G中的每个顶点 v ∈ V v\in V vV,遍历其邻接点列表中的每个邻接点 u u u

  3. 对于每个邻接点 u u u,将边 ( u , v ) (u,v) (u,v)添加到 G T G^T GT的邻接链表中,即将 u u u加入到 v v v的邻接点列表中。

下面是用Go语言实现上述算法的代码示例:

package mainimport "fmt"// 定义有向图的顶点结构
type Vertex struct {value intnext *Vertex
}// 定义有向图的邻接链表结构
type Graph struct {V intAdj []*Vertex
}// 函数实现有向图的转置操作
func transposeGraph(g *Graph) *Graph {transposed := &Graph{V: g.V, Adj: make([]*Vertex, g.V)}for u := 0; u < g.V; u++ {for v := g.Adj[u]; v != nil; v = v.next {transposed.Adj[v.value] = &Vertex{value: u, next: transposed.Adj[v.value]}}}return transposed
}func main() {// 举例一个有向图的邻接链表表示V := 4adj := make([]*Vertex, V)adj[0] = &Vertex{value: 1, next: &Vertex{value: 2, next: nil}}adj[1] = &Vertex{value: 2, next: nil}adj[2] = &Vertex{value: 0, next: &Vertex{value: 3, next: nil}}adj[3] = nilg := &Graph{V: V, Adj: adj}// 计算有向图的转置图transposed := transposeGraph(g)// 输出转置图的邻接链表表示for i := 0; i < transposed.V; i++ {fmt.Printf("顶点 %d 的邻接点: ", i)for v := transposed.Adj[i]; v != nil; v = v.next {fmt.Printf("%d ", v.value)}fmt.Println()}
}

该算法的运行时间为 O ( V + E ) O(V+E) O(V+E),其中 V V V为顶点数, E E E为边数。

chatgpt:

以下是使用邻接链表表示的图 G G G计算出 G T G^{T} GT的有效算法,并给出了相应的Go语言代码示例。

算法步骤:

  1. 创建一个空的图 G T G^{T} GT
  2. 遍历原图 G G G中的每个顶点 v v v,对于每个顶点 v v v,执行以下操作:
    • 如果 v v v在邻接链表中不存在,则将其加入邻接链表中
    • 遍历与顶点 v v v相关联的边 ( v , u ) (v, u) (v,u),其中 u u u为目标顶点。对于每条边 ( v , u ) (v, u) (v,u),将其反向添加到对应的邻接链表中:即将边 ( u , v ) (u, v) (u,v)添加到图 G T G^{T} GT的邻接链表中

代码示例(Go语言):

package mainimport "fmt"type Node struct {value intnext  *Node
}type Graph struct {vertices []*Node
}func NewGraph() *Graph {return &Graph{}
}func (g *Graph) addEdge(src, dest int) {newNode := &Node{value: dest, next: nil}if g.vertices[src] == nil {g.vertices[src] = newNode} else {curr := g.vertices[src]for curr.next != nil {curr = curr.next}curr.next = newNode}
}func (g *Graph) transpose() *Graph {transposedGraph := NewGraph()for i := range g.vertices {transposedGraph.vertices = append(transposedGraph.vertices, nil)}for i := range g.vertices {curr := g.vertices[i]for curr != nil {transposedGraph.addEdge(curr.value, i)curr = curr.next}}return transposedGraph
}func main() {graph := NewGraph()verticesCount := 5for i := 0; i < verticesCount; i++ {graph.vertices = append(graph.vertices, nil)}// 添加边graph.addEdge(0, 1)graph.addEdge(0, 2)graph.addEdge(1, 3)graph.addEdge(2, 3)graph.addEdge(3, 4)fmt.Println("原图 G:")for i, vertex := range graph.vertices {curr := vertexfor curr != nil {fmt.Printf("%d -> %d\n", i, curr.value)curr = curr.next}}transposedGraph := graph.transpose()fmt.Println("\n转置图 G^T:")for i, vertex := range transposedGraph.vertices {curr := vertexfor curr != nil {fmt.Printf("%d -> %d\n", i, curr.value)curr = curr.next}}
}

该算法的运行时间取决于顶点数和边数。假设有 n n n个顶点和 m m m条边,则构建邻接链表的时间复杂度为 O ( m ) O(m) O(m),转置操作需要遍历整个邻接链表,时间复杂度为 O ( n + m ) O(n+m) O(n+m)。因此,总体运行时间复杂度为 O ( n + m ) O(n+m) O(n+m)

注意:这只是一种实现方式,具体的算法细节和实现可能因应用场景和数据结构的不同而有所调整。

kimi:

首先,我们来分析两种图的表示方法:邻接链表和邻接矩阵,以及如何从图 ( G ) 计算出其转置图 ( G^T )。

邻接链表表示

邻接链表通常使用一个数组来表示,数组的每个元素是一个链表,链表中的每个节点代表一个邻接点和边的权重(如果有的话)。对于有向图 ( G ),如果 ( u ) 到 ( v ) 有一条边,那么在 ( u ) 的链表中会有一个指向 ( v ) 的节点。

算法步骤:

  1. 初始化一个新的邻接链表,其大小与 ( G ) 相同。
  2. 遍历原始图 ( G ) 的每个顶点 ( u )。
  3. 对于 ( u ) 的每个邻接点 ( v ),将 ( v ) 添加到 ( G^T ) 中 ( u ) 的链表中。
  4. 完成所有顶点的遍历后,( G^T ) 的邻接链表就构建好了。

时间复杂度:

  • 假设 ( G ) 有 ( n ) 个顶点和 ( m ) 条边。
  • 每个顶点的邻接链表遍历时间复杂度为 ( O(\text{deg}(u)) ),其中 ( \text{deg}(u) ) 是顶点 ( u ) 的度。
  • 总的时间复杂度为 ( O(m) ),因为每个边只被访问一次。

邻接矩阵表示

邻接矩阵是一个 ( n \times n ) 的矩阵,其中 ( n ) 是顶点的数量。如果 ( G ) 中 ( u ) 到 ( v ) 有边,则矩阵中的 ( G[u][v] ) 为 1(或边的权重),否则为 0。

算法步骤:

  1. 初始化一个与 ( G ) 同样大小的矩阵 ( G^T ),并将所有元素设置为 0。
  2. 遍历 ( G ) 的邻接矩阵,对于每个非零元素 ( G[u][v] ):
    • 将 ( G^T[v][u] ) 设置为 ( G[u][v] )。
  3. 完成所有元素的遍历后,( G^T ) 的邻接矩阵就构建好了。

时间复杂度:

  • 由于矩阵是 ( n \times n ),总的时间复杂度是 ( O(n^2) )。

Go 语言实现

以下是使用 Go 语言实现的邻接链表和邻接矩阵转置的示例代码:

package mainimport "fmt"// 邻接链表的节点
type AdjListNode struct {vertex intnext   *AdjListNode
}// 邻接链表的图
type GraphAdjList struct {adjList []*AdjListNodeV       int // 顶点的数量
}// 添加边
func (g *GraphAdjList) addEdge(v, w int) {newEdge := &AdjListNode{vertex: w, next: g.adjList[v]}g.adjList[v] = newEdge
}// 计算转置图的邻接链表
func (g *GraphAdjList) transpose() *GraphAdjList {gT := &GraphAdjList{V: g.V, adjList: make([]*AdjListNode, g.V)}for v := 0; v < g.V; v++ {for adj := g.adjList[v]; adj != nil; adj = adj.next {gT.addEdge(adj.vertex, v)}}return gT
}// 邻接矩阵的图
type GraphAdjMatrix struct {matrix [][]intV      int // 顶点的数量
}// 计算转置图的邻接矩阵
func (g *GraphAdjMatrix) transpose() *GraphAdjMatrix {gT := &GraphAdjMatrix{V: g.V, matrix: make([][]int, g.V)}for i := 0; i < g.V; i++ {gT.matrix[i] = make([]int, g.V)for j := 0; j < g.V; j++ {gT.matrix[i][j] = g.matrix[j][i]}}return gT
}func main() {// 示例:使用邻接链表和邻接矩阵构建图并计算其转置// 这里省略了图的构建过程,直接展示转置操作// ...
}

请注意,上述代码只是一个简单的示例,实际应用中可能需要更多的功能,例如图的构建、边的权重处理等。

混元:

为了计算有向图 G = ( V , E ) G=(V,E) G=(V,E) 的转置 G T = ( V , E T ) G^T=(V,E^T) GT=(V,ET),我们可以分别针对邻接链表和邻接矩阵两种表示方法给出相应的算法,并分析它们的运行时间。

邻接链表表示法

算法描述
  1. 初始化一个空的邻接链表来存储转置图的边。
  2. 遍历原图 G G G 的每个节点 u u u
  3. 对于节点 u u u 的每个邻接节点 v v v,在转置图中添加一条从 v v v u u u 的边。
  4. 返回转置图的邻接链表表示。
Go 语言实现
type AdjacencyList struct {V intAdj [][]int
}func TransposeAdjacencyList(graph AdjacencyList) AdjacencyList {V := graph.Vtransposed := make([][]int, V)for u := 0; u < V; u++ {for _, v := range graph.Adj[u] {transposed[v] = append(transposed[v], u)}}return AdjacencyList{V: V, Adj: transposed}
}
运行时间分析
  • 时间复杂度: O ( ∣ E ∣ ) O(|E|) O(E),其中 ∣ E ∣ |E| E 是原图的边数。因为我们需要遍历每条边来构建转置图。

邻接矩阵表示法

算法描述
  1. 初始化一个与原图 G G G 大小相同的邻接矩阵来存储转置图的边。
  2. 遍历原图 G G G 的每个节点对 ( u , v ) (u, v) (u,v)
  3. 如果 ( u , v ) (u, v) (u,v) 在原图中存在边,则在转置图的邻接矩阵中将 ( v , u ) (v, u) (v,u) 的对应位置设为边的权重(通常为1)。
  4. 返回转置图的邻接矩阵表示。
Go 语言实现
type AdjacencyMatrix struct {V intMat [][]int
}func TransposeAdjacencyMatrix(graph AdjacencyMatrix) AdjacencyMatrix {V := graph.Vtransposed := make([][]int, V)for i := range transposed {transposed[i] = make([]int, V)}for u := 0; u < V; u++ {for v := 0; v < V; v++ {if graph.Mat[u][v] != 0 {transposed[v][u] = graph.Mat[u][v]}}}return AdjacencyMatrix{V: V, Mat: transposed}
}
运行时间分析
  • 时间复杂度: O ( ∣ V ∣ 2 ) O(|V|^2) O(V2),其中 ∣ V ∣ |V| V 是原图的节点数。因为我们需要遍历矩阵中的每个元素来构建转置图。

在实际应用中,如果图的边数远小于节点数的平方,那么使用邻接链表表示法会更高效;反之,如果图的边数接近或超过节点数的平方,邻接矩阵表示法可能更合适。

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

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

相关文章

java LogUtil输出日志打日志的class文件内具体方法和行号

最近琢磨怎么把日志打的更清晰&#xff0c;方便查找问题&#xff0c;又不需要在每个class内都创建Logger对象&#xff0c;还带上不同的颜色做区分&#xff0c;简直不要太爽。利用堆栈的方向顺序拿到日志的class问题。看效果&#xff0c;直接上代码。 1、demo test 2、输出效果…

【WebGIS平台】传统聚落建筑科普数字化建模平台

基于上述概括出建筑单体的特征部件&#xff0c;本文利用互联网、三维建模和地理信息等技术设计了基于浏览器/服务器&#xff08;B/S&#xff09;的传统聚落建筑科普数字化平台。该平台不仅实现了对传统聚落建筑风貌从基础到复杂的数字化再现&#xff0c;允许用户轻松在线构建从…

Linux 利用命名空间创建一个自己的“容器“

Linux 利用命名空间创建一个自己的"容器" 前置条件 创建一个目录存放容器mkdir /myapp准备静态编译busybox&#xff0c;操作系统自带的往往是依赖动态库的(本文使用的debian apt install busybox-static) 开始 使用unshare起一个独立命名空间.# 进入后/myapp目录…

【自学网络安全】:安全策略与用户认证综合实验

实验拓扑图&#xff1a; 实验任务&#xff1a; 1、DMZ区内的服务器&#xff0c;办公区仅能在办公时间内(9:00-18:00)可以访问&#xff0c;生产区的设备全天可以访问 2、生产区不允许访问互联网&#xff0c;办公区和游客区允许访问互联网 3、办公区设备10.0.2.10不允许访问Dmz区…

新闻资讯整合平台:一站式满足企业信息需求

摘要&#xff1a; 面对信息爆炸的时代&#xff0c;企业如何在海量数据中快速获取有价值资讯&#xff0c;成为提升竞争力的关键。本文将探讨如何通过一站式新闻资讯整合平台&#xff0c;实现企业信息需求的全面满足&#xff0c;提升决策效率&#xff0c;同时介绍实用工具推荐&a…

Redis数据类型和数据队列

一.Redis数据类型 参考资料&#xff1a;http://www.redis.cn/topics/data-types.html 相关命令参考: http://redisdoc.com/ Redis 是一种基于内存的开源数据结构存储系统&#xff0c;支持多种数据类型&#xff0c;每种数据类型都有自己特定的操作命令。 String&#xff08;字…

Games101学习笔记 Lecture17 Materials and Appearances

Lecture17 Materials and Appearances 材质 BRDF一、Diffuse/Lambertian Material二、Glossy Material三、Ideal reflective/ refractive Material (BSDF)1.镜面反射2.镜面折射3.菲涅尔项 Fresnel 四、Microfacet BRDF 微表面五、Isotropic / Anisotropic Materials (BRDFs)An…

博客标题:C++中的继承:构建面向对象的基石

目录 ​编辑 引言 继承的基本形式 示例1&#xff1a;基本继承 继承的类型 示例2&#xff1a;不同类型的继承 多重继承 示例3&#xff1a;多重继承 继承与多态性 示例4&#xff1a;继承与多态 结论 结尾 引言 在面向对象编程&#xff08;OOP&#xff09;中&#xff…

【持续集成_03课_Linux部署Sonar+Gogs+Jenkins】

一、通过虚拟机搭建Linux环境-CnetOS 1、安装virtualbox&#xff0c;和Vmware是一样的&#xff0c;只是box更轻量级 1&#xff09;需要注意内存选择&#xff0c;4G 2、启动完成后&#xff0c;需要获取服务器IP地址 命令 ip add 服务器IP地址 通过本地的工具&#xff0c;进…

新手教学系列——crontab 使用不当引发的服务器性能问题

起因及症状 最近,我们的一台服务器随着运行时间的增加,逐渐出现了压力过大的问题。具体表现为数据库连接数飙升至 4000+,Redis 频繁超时,系统报错文件打开数过多等。针对这些问题,我们逐一检查了数据库连接池、Redis 连接池以及系统的 ulimit 配置,但都未能找到问题的根…

第241题| 确定极限中参数问题 | 武忠祥老师每日一题

解题思路&#xff1a;确定极限中的参数的方法是求这个极限&#xff1b;求极限根据类型选方法。 形可以用到三种方法&#xff1a;洛必达&#xff0c;等价&#xff0c;泰勒。 先观察题目&#xff0c;将看成一个整体&#xff0c;同时,并令,整理之后如下&#xff1a; 这里也要想办…

nginx.conf配置文件

1、全局模块 worker_processes 1; 工作进程数&#xff0c;一般设置成服务器内核数的2倍&#xff08;一般不超过8个&#xff0c;超过8个反而会降低性能&#xff0c;一般是4个&#xff0c;1-2个也可以&#xff09; 处理进程的过程必然涉及配置文件和展示页面&#xff0c;也就是…

2024.7.9作业

1、提示并输入一个字符串&#xff0c;统计该字符串中字母、数字、空格以及其他字符的个数 #include <stdio.h> #include <string.h> int main(int argc,const char *argv[]) { char arr[30]{0}; int zm0,kg0,sz0,qt0; printf("请输入字符串&…

智慧光伏一站式解决方案

光伏电站智慧化管理平台&#xff0c;将现代先进的数字信息技术、通信技术、互联网技术、云计算技术、大数据挖掘技术与光伏技术高度融合而形成。可以满足光伏企业对电站的高发电量、低初始投资、低运维成本等需求&#xff0c;从开发到运维的25年生命周期内&#xff0c;实现高收…

使用clion刷leetcode

如何优雅的使用clion刷leetcode 安装插件&#xff1a;LeetCode Editor) 插件配置&#xff1a; 这样我们每打开一个项目&#xff0c;就会创建类似的文件 我们的项目结构&#xff1a; 我们在题解文件中导入头文件myHeader.h并将新建的文件添加到cmakelists.txt文件&#xff0c;…

2024前端面试真题【JS篇】

DOM DOM&#xff1a;文本对象模型&#xff0c;是HTML和XML文档的编程接口。提供了对文档的结构化的表述&#xff0c;并定义可一种方式可以使从程序中对该结构进行访问&#xff0c;从而改变文档的结构、样式和内容。 DOM操作 创建节点&#xff1a;document.createElement()、do…

了解PPO算法(Proximal Policy Optimization)

Proximal Policy Optimization (PPO) 是一种强化学习算法&#xff0c;由 OpenAI 提出&#xff0c;旨在解决传统策略梯度方法中策略更新过大的问题。PPO 通过引入限制策略更新范围的机制&#xff0c;在保证收敛性的同时提高了算法的稳定性和效率。 PPO算法原理 PPO 算法的核心…

【docker 把系统盘空间耗没了!】windows11 更改 ubuntu 子系统存储位置

系统&#xff1a;win11 ubuntu 22 子系统&#xff0c;docker 出现问题&#xff1a;系统盘突然没空间了&#xff0c;一片红 经过排查&#xff0c;发现 AppData\Local\packages\CanonicalGroupLimited.Ubuntu22.04LTS_79rhkp1fndgsc\ 这个文件夹竟然有 90GB 下面提供解决办法 步…

Spring-AOP(二)

作者&#xff1a;月下山川 公众号&#xff1a;月下山川 1、什么是AOP AOP&#xff08;Aspect Oriented Programming&#xff09;是一种设计思想&#xff0c;是软件设计领域中的面向切面编程&#xff0c;它是面向对象编程的一种补充和完善&#xff0c;它以通过预编译方式和运行期…

【课程总结】Day13(下):人脸识别和MTCNN模型

前言 在上一章课程【课程总结】Day13(上):使用YOLO进行目标检测,我们了解到目标检测有两种策略,一种是以YOLO为代表的策略:特征提取→切片→分类回归;另外一种是以MTCNN为代表的策略:先图像切片→特征提取→分类和回归。因此,本章内容将深入了解MTCNN模型,包括:MTC…