C-星球游戏:简单优化,一次最短路
牛牛爱奇数
https://ac.nowcoder.com/acm/contest/6629/A
因为题目有的条件,所以可能有些同学就选择了跑多次最短路来解题。但这题其实可以通过简单的构造,一次最短路解决。
只需要加一个源点0,在源点和p中每个点之间连一条权值为0的边,然后跑一次以0为起点的单源最短路。
const int INF = 0x3f3f3f3f; class Solution { public: /** * * @param niuniu int整型vector 牛牛占领的p个星球的编号 * @param niumei int整型vector 牛妹占领的q个星球的编号 * @param path int整型vector<vector<>> m条隧道,每条隧道有三个数分别是ui,vi,wi。ui,vi分别是隧道的两边星球的编号,wi是它们之间的距离 * @param nn int整型 星球个数n * @return int整型 */ int Length(vector<int>& niuniu, vector<int>& niumei, vector<vector<int> >& path, int nn) { vector<vector<pair<int, int>>> adj(nn + 1); for (int i : niuniu) adj[0].emplace_back(i, 0); for (auto v : path) { adj[v[0]].emplace_back(v[1], v[2]); adj[v[1]].emplace_back(v[0], v[2]); } priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq; pq.push({0, 0}); vector<bool> vis(nn + 1); vector<int> dist(nn + 1, INF); dist[0] = 0; while (!pq.empty()) { pair<int, int> top = pq.top(); pq.pop(); int c = top.first, u = top.second; if (vis[u]) continue; vis[u] = true; for (pair<int, int> nxt : adj[u]) { int v = nxt.first, w = nxt.second; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.push({dist[v], v}); } } } int ans = INF; for (int i : niumei) ans = min(ans, dist[i]); if (ans == INF) return -1; return ans; } };