最短路
判断负环测试数据
5 4
1 2 1
3 4 -1
4 5 2
5 3 -4
Yes
5 10
2 1 10
3 1 3
4 1 2
2 4 10
5 5 1
5 2 2
2 2 1
2 4 8
1 2 10
3 4 9
No
判断负环代码
package main
import (
"bufio"
"fmt"
"os"
)
func _debug() {
const eof = 0
out := bufio.NewWriter(os.Stdout)
defer out.Flush()
_i, _n, buf := 0, 0, make([]byte, 1<<12) // 4KB
// 读一个字符
rc := func() byte {
if _i == _n {
_n, _ = os.Stdin.Read(buf)
if _n == 0 { // EOF
return eof
}
_i = 0
}
b := buf[_i]
_i++
return b
}
// 读一个整数,支持负数
ri := func() (x int) {
neg := false
b := rc()
for ; '0' > b || b > '9'; b = rc() {
// 某些多组数据的题目,不告诉有多少组数据,那么需要额外判断是否读到了 EOF
if b == eof {
return
}
if b == '-' {
neg = true
}
}
for ; '0' <= b && b <= '9'; b = rc() {
x = x*10 + int(b&15)
}
if neg {
return -x
}
return
}
// spfa判断环
n, m := ri(), ri() // n个点 m个边 s起点
graph := make([][]edge, n+1)
for ; m > 0; m-- {
a, b, c := ri(), ri(), ri()
graph[a] = append(graph[a], edge{b, c})
}
// 加入一个虚拟点 连向所有边的权均为0 然后再做spfa
for i := 0; i <= n; i++ {
graph[0] = append(graph[0], edge{i, 0})
}
// s := 0
dist := make([]int, n+1)
for i := range dist {
dist[i] = 1<<31 - 1
}
vis := make([]bool, n+1)
cnt := make([]int, n+1)
q := []int{}
for i := 1; i <= n; i++ {
q = append(q, i)
vis[i] = true
}
for len(q) != 0 {
u := q[0]
q = q[1:]
vis[u] = false
for _, ed := range graph[u] {
v := ed.to
w := ed.val
if dist[v] > dist[u]+w {
dist[v] = dist[u] + w
cnt[v] = cnt[u] + 1 // 记录边数
if cnt[v] >= n {
fmt.Fprintln(out, "Yes")
return
}
if !vis[v] {
q = append(q, v)
vis[v] = true
}
}
}
}
fmt.Fprintln(out, "No")
}
type edge struct {
to int
val int
}
func main() {
_debug()
}