题意分析
题目叫找有两个起点到终点的子权和,可以判断是最短路径问题
算法思路
2种情况。
- 2个起点到终点的路径没交集,直接分别求和
- 2个起点到终点的路径有交集,直接在交集后取较短那条路径即可,类似从3点出发,找到某点的最短距离。
代码实现
using ll=long long;
const ll inf=LLONG_MAX/3;
typedef pair<ll,ll> PII;
class Solution {
public:
long long minimumWeight(int n, vector<vector<int>>& edges, int src1, int src2, int dest) {
vector<vector<PII>> next(n);
vector<vector<PII>> prev(n);
for(auto & e:edges){
int a=e[0],b=e[1],w=e[2];
next[a].emplace_back(b,w);
prev[b].emplace_back(a,w);
}
vector<ll> dsrc1=dijkstra(n,src1,next);
vector<ll> dsrc2=dijkstra(n,src2,next);
vector<ll> desti=dijkstra(n,dest,prev);
ll ret=inf;
for(int i=0;i<n;i++){
ret=min(ret,dsrc1[i]+dsrc2[i]+desti[i]);//求3点到某点和最小
}
if(ret==inf) return -1;
else return ret;
}
vector<ll> dijkstra(int n,int start,vector<vector<PII>>&next){ //最短路径模板
vector<ll> dist(n,inf);
priority_queue<PII,vector<PII>,greater<>> q;
q.emplace(0,start);
while(!q.empty()){
auto [d,i]=q.top();q.pop();
if(dist[i]<inf) continue;
dist[i]=d;
for(auto & [nxt,weight]:next[i]){
if(dist[nxt]<inf) continue;
q.emplace(d+weight,nxt);
}
}
return dist;
}
};
解题总结
本题就是求2点出发边权和最小的情况,可以转化成包终点的3点出发到某点最短路的问题,通常会用到dijkstra算法,所以模板一定要牢记。