根据题意,需要知道左手与右手相遇的最小时间,因为左手和右手都能移动,所以建双层图,第一层为原图,第二层为反向图,两层之间变换无消耗,问题就从一开始的u->mid,v->mid转化成u->mid,mid->v,直接跑最短路,看能否从1到达二层图的对应点即可
AC代码:
#include <bits/stdc++.h> using namespace std; using LL = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; vector<vector<pair<int, int>>> G1(2 * n + 1); for (int i = 0; i < m; i++) { int u, v, c; cin >> u >> v >> c; G1[u].push_back(make_pair(v, c)); G1[v + n].push_back(make_pair(u + n, c)); } for (int i = 1; i <= n; i++) { G1[i].push_back(make_pair(i + n, 0)); } vector<LL> dist(2 * n + 1, 2E18); dist[1] = 0; set<pair<LL, LL>> se; for (int i = 1; i <= n; i++) { se.insert(make_pair(dist[i], i)); } while (!se.empty()) { int u = se.begin()->second; se.erase(se.begin()); for (auto v : G1[u]) { if (dist[v.first] > dist[u] + v.second) { se.erase(make_pair(dist[v.first], v.first)); dist[v.first] = dist[u] + v.second; se.insert(make_pair(dist[v.first], v.first)); } } } for (int i = 2; i <= n; i++) { if (dist[i + n] == 2E18) { cout << "-1 "; } else { cout << dist[i + n] << " "; } } cout << '\n'; return 0; }
M. Moving Both Hands(最短路)
最新推荐文章于 2024-08-15 05:02:54 发布