题意分析
这题又是道求起点到终点的权值和最小的问题,一看到有起点到终点,有权值无向图,尽管要"充电",也就是权值加了一部分而已,直接dijkstra解决。唯一的难点是这里加了限制条件,充电有容量,所以不能按最短路径充电,要考虑充电状态是否合乎条件。
算法思路
参考某大佬
- 创建(index,charge)的二元数组,记录充电状态
- 每次如果电量足够到达对面,则将当前顶点时间、电量更新,放入队列。
如果不够,就在限制条件下充电,把每一个充电状态更新到队列中,回到循环
代码实现
typedef pair<int,int> PII;
const int inf=INT_MAX/2;
typedef array<int,3> AI3;
class Solution {
public:
int electricCarPlan(vector<vector<int>>& paths, int cnt, int start, int end, vector<int>& charge) {
int n=charge.size();
vector<vector<int>> dist(n,vector<int>(cnt+1,inf));
dist[start][0]=0;
vector<vector<PII>> g(n);
for(auto & e:paths){
int a=e[0],b=e[1],c=e[2];
g[a].emplace_back(b,c);
g[b].emplace_back(a,c);
}
priority_queue<AI3,vector<AI3>,greater<>> q;
q.push({0,start,0});
while(!q.empty()){
auto [t,i,c]=q.top();q.pop();
if(t<dist[i][c]) continue;
if(i==end) return t;
dist[i][c]=t;
for(auto & [nxt,w]:g[i]){
if(c-w>=0 && t+w<dist[nxt][c-w]){
dist[nxt][c-w]=t+w;
q.push({t+w,nxt,c-w});
}
}
if(c<cnt){
int nt=t+charge[i];
if(nt<dist[i][c+1]){
dist[i][c+1]=nt;
q.push({nt,i,c+1});
}
}
}
return -1;
}
};
解题总结
加了限制的dijkstra在这里是用了暴力枚举,逐一匹配状态,状态思想值得学习。