题意:给定一个带权有向图,以及两个起始点,一个终点,问是否存在一个连通图,使得两个起始点能到达终点,且权值最小。
传送门
输入:n = 6, edges = [[0,2,2],[0,5,6],[1,0,3],[1,4,5],[2,1,1],[2,3,3],[2,3,4],[3,4,2],[4,5,1]], src1 = 0, src2 = 1, dest = 5
输出:9
解释:
上图为输入的图。
蓝色边为最优子图之一。
注意,子图 [[1,0,3],[0,5,6]] 也能得到最优解,但无法在满足所有限制的前提下,得到更优解。
题解:dijkstra
long long minimumWeight(int n, vector<vector<int>>& edges, int src1, int src2, int dest) {
#define ll long long
vector<pair<int,int>> fnes[n], bnes[n];
for(auto& e : edges) {
fnes[e[0]].emplace_back(e[1], e[2]);
bnes[e[1]].emplace_back(e[0], e[2]);
}
auto get_path = [&](int s, vector<pair<int, int>> nes[], vector<ll>& dist) {
priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> q;
dist[s] = 0;
q.emplace(0, s);
while(q.size()) {
auto [cost, node] = q.top();
q.pop();
if(cost > dist[node]) continue;
for(auto[ne, w] : nes[node]) {
if(cost + w < dist[ne]) {
dist[ne] = cost + w;
q.emplace(cost + w, ne);
}
}
}
};
vector<ll> dist1(n, 1e15), dist2(n, 1e15), dist3(n, 1e15);
get_path(src1, fnes, dist1);
get_path(src2, fnes, dist2);
get_path(dest, bnes, dist3);
ll ret = 1e15;
for(int i = 0; i < n; ++i) {
ret = min(ret, dist1[i] + dist2[i] + dist3[i]);
}
if(ret > 1e12) return -1;
return ret;
}