3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rustのpetgraphクレートを使ってAtCoderのグラフ問題を解く

Last updated at Posted at 2020-09-07

はじめに

AtCoderの言語アップデートによりRustでいろいろなクレート(ライブラリ)が使えるようになりました。

ここではグラフアルゴリズムを提供するpetgraphクレートを使ってグラフの問題を解いてみます。

ABC 070 D - Transit Tree Path

問題概要
n頂点の木とQ個のクエリと整数Kが与えられます。
j(1<=j<=Q)番目のクエリ:頂点xjから頂点Kを経由した頂点yjまでの最短距離を求めよ

制約概要
3<= N <= 10^5
1<= Q <= 10^5
1 <= K <= N
1 <= xj, yj <= N(1 <= j <= Q)
xj != yj(1<= j <= Q)
xj != K, yj != K(1 <= j <= Q)

use petgraph::algo::dijkstra;
use petgraph::graph::{NodeIndex, UnGraph};
use proconio::input;

fn main() {
    input! {
        n: usize,
        edges: [(usize, usize, usize); n-1],
        q: usize,
        k: usize,
        pairs: [(usize, usize); q],
    }

    //グラフを作る。
    let g = UnGraph::<usize, usize, usize>::from_edges(&edges);

    //ダイクストラ法で頂点kから他の頂点の最短距離を計算
    let res = dijkstra(&g, k.into(), None, |e| *e.weight());


    for (start, end) in &pairs {
        //頂点x_jと頂点kの最短距離 + 頂点kと頂点y_jの最短距離を計算
        let distance =
            res.get(&NodeIndex::new(*start)).unwrap() + res.get(&NodeIndex::new(*end)).unwrap();
        println!("{}", distance);
    }
}

解法
頂点xjから頂点Kを経由した頂点yjまでの最短距離というのは頂点xjと頂点Kの最短距離+頂点kと頂点yjの最短距離と等しいです。したがって事前に頂点Kから他の頂点の最短距離を求めておけば各クエリはO(1)で処理できます。

おわりに

petgraphクレートを使うことでグラフとアルゴリズムを一切実装せず、解くことができました。petgraphクレートにはほかにも様々なデータ構造やアルゴリズムが存在するので使いこなせれば、力強い味方になってくれそうな気がします。

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?