Network Delay Time 网络延迟时间

有 N 个网络节点,标记为 1 到 N

给定一个列表 times,表示信号经过有向边的传递时间。 times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节点传递到目标节点的时间。

现在,我们向当前的节点 K 发送了一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1

注意:

  1. N 的范围在 [1, 100] 之间。
  2. K 的范围在 [1, N] 之间。
  3. times 的长度在 [1, 6000] 之间。
  4. 所有的边 times[i] = (u, v, w) 都有 1 <= u, v <= N 且 1 <= w <= 100

思路:这道题其实就是单源最短路劲的问题(即在图中给定节点K,其他所有节点距离K的距离),主要解法有Dijkstra’s algorithm和Bellman–Ford Algorithm解法。接下来分别说下:

思路一:迪杰斯特拉解法,最常见的解法是不使用任何辅助,类似于BFS每次向外拓展一圈。时间复杂度O(n^2),n表示节点。

参考代码:

class Solution {
public:
int minDistance(vector<bool> &sptSet, vector<int> &dict) {
	int minValue = INT_MAX, int_index;
	for (int i = 1; i < dict.size(); i++) {
		if (!sptSet[i] && dict[i]<= minValue) {
			minValue = dict[i]; int_index = i;
		}
	}
	return int_index;
}
int networkDelayTime(vector<vector<int>>& times, int N, int K) {
	if (times.empty()) return -1;
	vector<vector<int>> ad_matrix(N + 1, vector<int>(N + 1, -1));
	for (auto time : times) ad_matrix[time[0]][time[1]] = time[2];
	vector<bool> sptSet(N + 1, false);
	vector<int> dict(N + 1, INT_MAX);
	sptSet[0] = true;
	dict[K] = 0;
	for (int i = 1; i <= (N - 1); i++) {
		int u = minDistance(sptSet, dict);
		sptSet[u] = true;
		for (int v = 1; v <= N; v++) {
			if (!sptSet[v] && dict[u] != INT_MAX && ad_matrix[u][v] != -1 && dict[v] > (dict[u] + ad_matrix[u][v])) {
				dict[v] = dict[u] + ad_matrix[u][v];
			}
		}
	}
	int res = 0;
	for (int i = 1; i <= N; i++) {
		if (dict[i] == INT_MAX) return -1;
		res = max(res, dict[i]);
	}
	return res;
}
};

思路二:采用了最小堆,每次从堆中取出距离最短的节点,时间复杂度为O(vlogv)。

参考代码:

class Solution {
public:
struct networkDelayTimeCmp {
	bool operator()(const pair<int, int> &a, const pair<int, int> &b) {
		return a.second > b.second;
	}
};

unordered_map<int, vector<vector<int>>> make_graph(vector<vector<int>>& times, int N) {
	unordered_map<int, vector<vector<int>>> res;
	for (auto node : times) {
		if (res.find(node[0]) == res.end()) res[node[0]] = { {node[1],node[2]} };
		else {
			vector<vector<int>> old = res[node[0]];
			old.push_back({ node[1],node[2] });
			res[node[0]] = old;
		}
	}
	return res;
}
int networkDelayTime(vector<vector<int>>& times, int N, int K) {
	if (times.empty()) return -1;
	priority_queue<pair<int, int>, vector<pair<int, int>>, networkDelayTimeCmp> q;
	unordered_map<int, vector<vector<int>>> map = make_graph(times, N);
	vector<int> dict(N+1,INT_MAX);
	dict[K] = 0;
	q.push({K,0});
	while (!q.empty()) {
		auto closest = q.top(); q.pop();
		if (map.find(closest.first) != map.end()) {
			for (auto neibors : map[closest.first]) {
				int v = neibors[0];
				int weight = neibors[1];
				int u = closest.first;
				if ((long)(dict[v]) > (long)(dict[u] + weight)) {
					dict[v] = (dict[u] + weight);
					q.push({v,dict[v]});
				}
			}
		}
	}
	int res = 0;
	for (int i = 1; i <= N;i++) {
		if (dict[i]==INT_MAX) {
			return -1;
		}
		res = max(res, dict[i]);
	}
	return res;
}
};

思路三:最后是bellman算法,时间复杂度为O(vloge)(v表示节点,e表示边)

参考代码:

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int N, int K) {
	if (times.empty()) return -1;
	vector<int> dict(N + 1, INT_MAX);
    dict[K]=0;
	for (int i = 1; i < N; i++) {
		for (auto time : times) {
			int u = time[0], v = time[1], w = time[2];
			if (dict[u] != INT_MAX && dict[v] > (dict[u] + w)) {
				dict[v] = dict[u] + w;
			}
		}
	}
	int res = 0;
	for (int i = 1; i <= N; i++) {
		if (dict[i] == INT_MAX) return -1;
		res = max(res, dict[i]);
	}
	return res;        
    }
};

猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/82828625