There are N network nodes, labelled 1 to N.
Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time it takes for a signal to travel from source to target.
Now, we send a signal from a certain node K. How long will it take for all nodes to receive the signal? If it is impossible, return -1.
Note:
N will be in the range [1, 100].
K will be in the range [1, N].
The length of times will be in the range [1, 6000].
All edges times[i] = (u, v, w) will have 1 <= u, v <= N and 1 <= w <= 100.
解决这题需要图的相关方面的知识。尤其是图的广度遍历的知识。
具体的遍历过程如下
这里的目的是求出网络从一个源点发布信息到这个图中,问至少需要多长的时间。这里我们将网络抽象成一个图的结构,从源点到某个点信息的传播可以看成是图的一条路径。那么何时才会有当所有的点都收到信息的时候时间确最短呢?为了时间最少,我们必须确保源点到每一个点的路径是最短的,同时,为了让所有的点都能收到的话,我们必须在这些最短的路径中取需要的时间最长的。那么问题就转化为求图某个点到所有点的最短路径,并取出其中的最大值。再看题目数据的特点,路径的权值是正数,说明Dijkstra算法是合适的,那么Bellman-Ford算法也必定合适。
首先,我们需要对图用合适的数据结构表示出来,由于在找最小路径的时候需要遍历同一个起点的所有边,那么我们需要将同一起点的边表示在一起,同时还需要保存权重,所以我最后决定用map
Dijkstra算法
class Solution {
public:
int networkDelayTime(vector>& times, int N, int K) {
/*build a graph
* the key of map is the source
* the first element of vector is the target
* the second is the distance
*/
int count = 0;
map > > graph;
for(auto a : times) {
vector temp;
temp.push_back(a[1]);
temp.push_back(a[2]);
graph[a[0]].push_back(temp);
}
//the min distance
vector dist(N+1, INT_MAX);
dist[K] = 0;
//array to tag weather the element is visited
vector array_queue(N+1, INT_MAX);
vector bool_(N+1, false);
array_queue[K] = 0;
int index = 0;
while(count < N) {
int min = INT_MAX;
for(int i = 1; i < array_queue.size(); i++) {
if(bool_[i] == false) {
if(array_queue[i] < min) {
min = array_queue[i];
index = i;
}
}
}
bool_[index] = true;
count++;
//cout << "index " << index << endl;
//find the distance
for(int i = 0; i < graph[index].size(); i++) {
//cout << "graph[index][i][0] " << graph[index][i][0] << endl;
if(dist[graph[index][i][0]] > dist[index] + graph[index][i][1]) {
dist[graph[index][i][0]] = dist[index] + graph[index][i][1];
array_queue[graph[index][i][0]] = dist[graph[index][i][0]];
}
}
}
int result = -1;
for(int i = 1; i < N+1; i++) {
if(dist[i] == INT_MAX) {
return -1;
}
if(dist[i] > result) {
result = dist[i];
}
}
return result;
}
};
利用队列优化Bellman-Ford算法
class Solution {
public:
int networkDelayTime(vector>& times, int N, int K) {
/*build a graph
* the key of map is the source
* the first element of vector is the target
* the second is the distance
*/
int count = 0;
map > > graph;
for(auto a : times) {
vector temp;
temp.push_back(a[1]);
temp.push_back(a[2]);
graph[a[0]].push_back(temp);
}
//the min distance
vector dist(N+1, INT_MAX);
vector visited(N+1, false);
dist[K] = 0;
queue q;
set s;
q.push(K);
s.insert(K);
while(!q.empty()) {
int index = q.front();
s.erase(index);
visited[index] = true;
//cout << index << endl;
q.pop();
for(int i = 0; i < graph[index].size(); i++) {
if(dist[graph[index][i][0]] > dist[index] + graph[index][i][1]) {
dist[graph[index][i][0]] = dist[index] + graph[index][i][1];
if(s.find(graph[index][i][0]) == s.end())
q.push(graph[index][i][0]);
}
}
}
int result = -1;
for(int i = 1; i < N+1; i++) {
if(dist[i] == INT_MAX) {
return -1;
}
if(dist[i] > result) {
result = dist[i];
}
}
return result;
}
};