目录
- 题目描述
- 解题思路
- 完整代码
题目描述
解题思路
这题可以通过Dijkstra算法求解。由于要求所有节点都收到信号所需的时间,可以用vector存储每个节点收到信号的时间,最后排序,如果有节点没有被更新(仍是初始的很大的值),则表示有节点没有收到信号,返回-1,否则返回时间的最大值。
首先,为了避免重复访问,用edges记录每条边,time记录每条边的值:
vector<vector<int>> edges(N);//edges[i]表示以节点i为源节点的目标节点集合
for(int i = 0; i < times.size(); i++) {
//注意,题目的节点标记为1到N,而此解法的节点标记实际为0到N-1,如edges[i]中,节点i对应于题目中的节点i+1
edges[times[i][0] - 1].push_back(times[i][1] - 1);
time[times[i][0] - 1][times[i][1] - 1] = times[i][2];
}
node_time[i]表示节点i收到信号的时间,将所有节点收到信号的时间都设为10000(尽可能大),同时,将节点K的时间设为0:
for(int i = 0; i < N; i++) {
node_time.push_back(10000);
}
int k = K - 1;
node_time[k] = 0;
用Dijkstra算法求解后,对得到的每个节点收到信号的时间进行排序,并根据情况返回结果:
dijkstra(k, edges);
sort(node_time.begin(), node_time.end());
return node_time[N - 1] == 10000 ? -1 : node_time[N - 1];
Dijkstra算法中,使用优先队列,这样要比将元素逐个插入队列的操作快得多:
priority_queue<P,vector<P>,greater<P> > q;
q.push(P(0, K));
完整代码
typedef pair<int,int> P;
class Solution {
public:
int networkDelayTime(vector<vector<int>>& times, int N, int K) {
vector<vector<int>> edges(N);
for(int i = 0; i < times.size(); i++) {
edges[times[i][0] - 1].push_back(times[i][1] - 1);
time[times[i][0] - 1][times[i][1] - 1] = times[i][2];
}
for(int i = 0; i < N; i++) {
node_time.push_back(10000);
}
int k = K - 1;
node_time[k] = 0;
dijkstra(k, edges);
sort(node_time.begin(), node_time.end());
return node_time[N - 1] == 10000 ? -1 : node_time[N - 1];
}
void dijkstra(int K, vector<vector<int>>& edges) {
//创建优先队列
priority_queue<P,vector<P>,greater<P> > q;
q.push(P(0, K));
while(!q.empty()) {
P p = q.top(); q.pop();
int u = p.second;
for(int i = 0; i < edges[u].size(); i++) {
if(node_time[edges[u][i]] > node_time[u] + time[u][edges[u][i]]) {
node_time[edges[u][i]] = node_time[u] + time[u][edges[u][i]];
q.push(P(node_time[edges[u][i]], edges[u][i]));
}
}
}
}
private:
int time[100][100];//time[u][v]表示边(u,v)的值
vector<int> node_time;//node_time[i]表示节点i收到信号的时间
};