原题链接
学习一手jiangly哥哥的代码
dij取消vis的使用,采用优先队列<权重,点>的形式入队,代码简洁优美。 针对本题,采用奇数偶数分开的形式判断有无上马,增加一倍的顶点数。
再一次膜拜哥哥ing
建图
1 2 3 4 5 6 7 8 9 std::vector<std::vector<std::array<int , 2>>> adj (n); for (int i = 0 ; i < m; i++) { int u, v, w; std::cin >> u >> v >> w; u--; v--; adj[u].push_back ({v, w}); adj[v].push_back ({u, w}); }
dijkstra最短路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 auto dijkstra = [&](int s) { std::vector<i64> dis (2 * n, inf); std::priority_queue<std::pair<i64, int >, std::vector<std::pair<i64, int >>, std::greater<>> pq; pq.emplace (0LL , 2 * s); while (!pq.empty ()) { auto [d, u] = pq.top (); pq.pop (); if (dis[u] != inf) { continue ; } dis[u] = d; int x = u / 2 ; int t = u % 2 ; if (!t && horse[x]) { pq.emplace (d, 2 * x + 1 ); } for (auto [y, w] : adj[x]) { pq.emplace (d + (t ? w / 2 : w), 2 * y + t); } } std::vector<i64> d (n, inf) ; for (int i = 0 ; i < n; i++) { d[i] = std::min (dis[2 * i], dis[2 * i + 1 ]); } return d; };
转换成普通dij模板如下
建图
1 2 3 4 5 6 vector<vector<pair<ll,ll>>> g (n+1 ); while (m--){ ll u,v,w; cin >> u >> v >> w; g[u].push_back ({v,w}); }
dij本体
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 auto dijkstra = [&](int s) { vector<ll> dis (n+1 , INF); priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<>> pq; pq.emplace (0LL , s); while (!pq.empty ()) { auto [d, u] = pq.top (); pq.pop (); if (dis[u] != INF) { continue ; } dis[u] = d; for (auto [y, w] : g[u]) { pq.emplace (d + w, y ); } } return dis; };
使用
1 2 3 4 auto dis = dijkstra (s);for (int i=1 ;i<=n;i++){ cout<<dis[i]<<" \n" [i==n]; }
洛谷模板题测试,成功!
by
Heshi
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE