文心一言 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.pswp.cn/web/42663.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42663.shtml
英文地址,請注明出處:http://en.pswp.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目錄…

Python中生成隨機數:一種簡單而強大的方法

簡介&#xff1a; 在編程中&#xff0c;我們經常需要生成隨機數來模擬各種情況&#xff0c;比如游戲、統計模擬、機器學習數據集的劃分等。Python通過其內置的random模塊提供了一個簡單而強大的方式來生成隨機數。本文將介紹如何使用random模塊來生成各種類型的隨機數&#xff…

【RESTful】前后端的通信方式 REST

前后端的通信方式 REST 1.初識 REST1.1 什么是 REST1.2 REST 的特征 2.HTTP 方法與 CRUD 動作映射3.實現 REST 風格的 CRUD 1.初識 REST 1.1 什么是 REST REST 是軟件架構的規范體系結構&#xff0c;它將 資源的狀態 以適合客戶端的形式從服務器端發送到客戶端&#xff08;或…

小型簡易GIT服務器搭建和使用

搭建GIT服務器的文章有很多&#xff0c;多數在管理的時候都使用了gitosis作為管理工具&#xff0c;但是作為一個小團隊(人數少于50人)&#xff0c;我覺得完全可以使用公鑰驗證的方式&#xff0c;這樣會簡單不少&#xff0c;下面來看看簡易的搭建方法吧。 服務器版本:ubuntu 16…

Unix\Linux 執行shell報錯:“$‘\r‘: 未找到命令” 解決

linux執行腳本sh xxx.sh報錯&#xff1a;$xxx\r: 未找到命令 原因&#xff1a;shell腳本在Windows編寫導致的換行問題&#xff1a; Windows 的換行符號為 CRLF&#xff08;\r\n&#xff09;&#xff0c;而 Unix\Linux 為 LF&#xff08;\n&#xff09;。 縮寫全稱ASCII轉義說…

第二證券:ppi指數是什么,ppi指數下降對股市有什么影響?

PPI全稱Producer Price Index&#xff0c;PPI指數即“出產者價格指數”&#xff0c;反映的是一守時期內出產者購買中心產品和原材料價格的改動趨勢和改動程度。 了解ppi指數&#xff1a; 簡單了解便是&#xff0c;計算出出產者的本錢改動狀況&#xff0c;然后反映到價格上。 …

windows@windows設備之間遠程命令行控制方案@windows設備間使用OpenSSH

文章目錄 abstract為什么考慮命令行連接討論主題 powershell遠程控制使用PowerShell遠程管理前提條件&#xff1a;步驟&#xff1a;1. 啟用WinRM服務2. 配置信任主機3. 測試連接4. 創建遠程會話5. 運行遠程命令6. 關閉會話 例子小結 SSH方案基礎連接免密自動登錄修改配置文件在…

【自學網絡安全】:安全策略與用戶認證綜合實驗

實驗拓撲圖&#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; 這里也要想辦…

mysql怎么調整緩沖區大小

MySQL中調整緩沖區大小是數據庫性能優化的重要一環。緩沖區大小直接影響了數據庫的讀寫性能和響應速度。以下是一些常見的MySQL緩沖區及其調整方法&#xff1a; 一、InnoDB緩沖池&#xff08;InnoDB Buffer Pool&#xff09; InnoDB緩沖池是InnoDB存儲引擎用來緩存表數據和索…

代碼隨想錄第7天 454 、 383 、15、18

代碼隨想錄第7天 454. 四數相加 II 思路就是先統計nums1和num2各個元素之和出現的次數&#xff0c;然后遍歷num3和nums4各個元素之和&#xff0c;看其相反數是否在map中&#xff0c;若在加上出現次數 class Solution { public: int fourSumCount(vector<int> &num…

nginx.conf配置文件

1、全局模塊 worker_processes 1; 工作進程數&#xff0c;一般設置成服務器內核數的2倍&#xff08;一般不超過8個&#xff0c;超過8個反而會降低性能&#xff0c;一般是4個&#xff0c;1-2個也可以&#xff09; 處理進程的過程必然涉及配置文件和展示頁面&#xff0c;也就是…