0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ABC361 Eの解法メモ【Ruby】

Posted at

入水目指して過去挑戦して解けてないAtCoder Problems上でDifficultyが水色の問題を解いていく。

ABC361 E: Tree and Hamilton Path 2概要

辺に重みを持つ木に対して、辺をたどってすべての頂点を訪れるときに経由した辺の重みの合計の最小値を求める問題。

解法イメージ

入力例1をベースに考える。
入力例1の木は頂点1から頂点2,3,4のそれぞれに辺が伸びている構造をしている。
この木に対してすべての頂点を訪れるような経路の例を考えてみると、$ 1 \rightarrow 2 \rightarrow 1 \rightarrow 3 \rightarrow 1 \rightarrow 4 $のような経路がある。

上記の経路のように、頂点2,3,4のような辺を一つしか持たない"行き止まり"の頂点は始点と終点にならない限り、辺を往復することになる。
逆に1度のみ経由で済む辺を考えてみると、始点から終点までをつなぐパスは戻ってくる必要がないため1度のみの移動で済む。それ以外の辺については始点と終点をつなぐパスに戻ってくる必要があるので、往復の2回通る必要が出てくる。
よって、すべての頂点を訪れるような経路の辺の重みの合計は、すべての辺の重みの合計の2倍から始点と終点をつなぐパスの重みの合計を引いたものになる。
この最小値を求めるとよいので、始点から終点までの辺の重みの合計が最大になるようなパスをみつければよい。
つまり木の直径を求めればよいので、直径を求めるアルゴリズムを使えばよい。

実装例

def dfs(first, hash)
  last = 0
  length = 0
  set = { first => true }
  queue = [[first, 0]]
  while queue.length > 0
    a, len = queue.pop
    hash[a].each do |b, blen|
      next if set[b]
    
      set[b] = true
      queue << [b, len + blen]
      if length < len + blen
        last = b
        length = len + blen
      end
    end
  end
  return last, length
end

n = gets.to_i
hash = Hash.new { |hash, key| hash[key] = {} }
sum = 0
(n-1).times do
  a, b, l = gets.split.map(&:to_i)
  hash[a][b] = l
  hash[b][a] = l
  sum += l
end

si, _ = dfs(1, hash)
puts 2 * sum - dfs(si, hash)[1]
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?