ABC
D - Shortest Path 3

D - Shortest Path 3

キーワード

解説

問題 (opens in a new tab)

ダイクストラ法を使う。ただし、頂点にも重みがあるので、暫定距離に頂点の重みも加える。

ダイクストラ法は ダイクストラ法を参照。

提出コード

  • Go
func main() {
	var n, m int
	scanIntVariables(&n, &m)
	A := readInts()
	G := make([][][2]int, n+1)
	for i := 1; i <= n; i++ {
		G[i] = [][2]int{}
	}
	for i := 0; i < m; i++ {
		var a, b, c int
		scanIntVariables(&a, &b, &c)
		G[a] = append(G[a], [2]int{b, c})
		G[b] = append(G[b], [2]int{a, c})
	}
	D := make([]int, n+1) // 頂点1からの最短経路のコスト
	for i := 1; i <= n; i++ {
		D[i] = math.MaxInt64
	}
	D[1] = A[0]
	kakutei := make([]bool, n+1)
	q := priorityqueue.New[[2]int](func(a, b [2]int) int { return a[0] - b[0] })
	q.Push([2]int{D[1], 1})
	for !q.Empty() {
		u := q.Pop()[1]
		if kakutei[u] {
			continue
		}
		kakutei[u] = true
		for _, e := range G[u] {
			v, c := e[0], e[1]
			if D[v] > D[u]+c+A[v-1] {
				D[v] = D[u] + c + A[v-1]
				q.Push([2]int{D[v], v})
			}
		}
	}
	for i := 2; i <= n; i++ {
		write(D[i], " ")
	}
	writeLine()
}
  • C++
int main() {
    int n,m; cin >> n >> m;
    vector<ll> A(n); rep(i,0,n) cin >> A[i];
    vector<vector<pair<int,ll>>> G(n);
    rep(i,0,m) {
        int u,v; ll w; cin >> u >> v >> w;
        u--; v--;
        G[u].push_back({v,w});
        G[v].push_back({u,w});
    }
    vector<ll> D(n,LLONG_MAX);
    D[0] = A[0];
    auto cmp = [](pair<ll,int> a, pair<ll,int> b) { return a.first > b.first; };
    priority_queue<pair<ll, int>, vector<pair<ll,int>>, decltype(cmp)> que(cmp);
    que.push({D[0],0});
    while(!que.empty()) {
        auto p = que.top(); que.pop();
        int u = p.second;
        ll d = -p.first;
        if (D[u] < d) continue;
        for(auto e: G[u]) {
            int v = e.first;
            ll w = e.second;
            if (D[v] > D[u] + w + A[v]) {
                D[v] = D[u] + w + A[v];
                que.push({-D[v],v});
            }
        }
    }
 
    rep(i,1,n) cout << D[i] << endl;
}