3112. 访问消失节点的最少时间
思路:节点n的个数非常大,用普通的dijkstra算法对节点进行枚举是会超时的,时间复杂度为0(n^2)。这里边的数量最大为10 ^5,可以对边使用dijkstra算法+堆优化操作,时间复杂度为0(mlogm)。
节点消失问题,只需要加一个判断条件,判断到每个节点的最小时间是否都低于消失时间,如果不低于说明到不了,直接跳过即可。细节看注释。
class Solution {
public:
typedef pair<int,int> PII;
vector<int> minimumTime(int n, vector<vector<int>>& edges, vector<int>& disappear) {
//邻接表
vector<vector<PII>> g(n);
for(int i=0;i<edges.size();i++){
g[edges[i][0]].push_back({edges[i][1],edges[i][2]});
g[edges[i][1]].push_back({edges[i][0],edges[i][2]});
}
//到每个节点的最小值,-1表示还没到过
vector<int> dis(n,-1);
//按最小时间进行升序排列的优先队列
priority_queue<PII,vector<PII>,greater<PII>> qu;
//插入0节点的情况
qu.push({0,0});
while(qu.size()){
PII tmp=qu.top();
qu.pop();
//如果当前节点没有遍历过,或者有更小的时间到达
if(dis[tmp.second]==-1||tmp.first<dis[tmp.second]){
dis[tmp.second]=tmp.first;
}else{
continue;
}
//枚举当前点tmp.second能到的其他节点
for(int i=0;i<g[tmp.second].size();i++){
//如果可以在消失前到达,那就加入队列
if(g[tmp.second][i].second+tmp.first<disappear[g[tmp.second][i].first])
qu.push({g[tmp.second][i].second+tmp.first,g[tmp.second][i].first});
}
}
return dis;
}
};