有 N 个网络节点,标记为 1 到 N。
给定一个列表 times,表示信号经过有向边的传递时间。 times[i] = (u, v, w),其中 u 是源节点,v 是目标节点, w 是一个信号从源节点传递到目标节点的时间。
现在,我们从某个节点 K 发出一个信号。需要多久才能使所有节点都收到信号?如果不能使所有节点收到信号,返回 -1。
示例:
输入:times = [[2,1,1],[2,3,1],[3,4,1]], N = 4, K = 2
输出:2
代码
class Solution {
HashMap<Integer, List<int[]>> map;HashMap<Integer,Integer> dist;
public int networkDelayTime(int[][] times, int N, int K) {
dist=new HashMap<>();
map=new HashMap<>();
boolean[] check=new boolean[N+1];
for(int[] time:times)//构造邻接表
{ if(!map.containsKey(time[0]))
map.put(time[0], new ArrayList<int[]>());
map.get(time[0]).add(new int[]{time[1],time[2]});
}
for(int i=1;i<=N;i++)
dist.put(i,Integer.MAX_VALUE);
dist.put(K,0);
while (true)
{
int curDist=Integer.MAX_VALUE;
int curNode=-1;
for(int i=1;i<=N;i++)
if(!check[i]&&dist.get(i)<curDist)//找出当前距离起点的最近的节点
{
curDist=dist.get(i);
curNode=i;
}
if(curNode<0) break;//遍历完了所有节点
check[curNode]=true;//当前节点已经被访问
if(map.containsKey(curNode))
{
for(int[] next:map.get(curNode))//更新邻接点与起点的最小距离
dist.put(next[0], Math.min(next[1]+dist.get(curNode),dist.get(next[0])));
}
}
int cnt=0;
for(int c:dist.values())//遍历所有的节点到起点的距离
{ if(c==Integer.MAX_VALUE) return -1;
cnt= Math.max(c,cnt);}
return cnt;
}
}
堆实现代码
HashMap<Integer, List<int[]>> map;
public int networkDelayTime(int[][] times, int N, int K) {
HashMap<Integer,Integer> dist=new HashMap<>();
map=new HashMap<>();
boolean[] check=new boolean[N+1];
for(int[] time:times)//构造邻接表
{ if(!map.containsKey(time[0]))
map.put(time[0], new ArrayList<int[]>());
map.get(time[0]).add(new int[]{time[1],time[2]});
}
PriorityQueue<int[]> priorityQueue=new PriorityQueue<>(((o1, o2) -> o1[0]-o2[0]));//按距离从小到大
priorityQueue.offer(new int[]{0,K});//将起点加入优先队列
while (!priorityQueue.isEmpty())
{
int[] temp=priorityQueue.poll();
int d=temp[0],node=temp[1];
if(dist.containsKey(node)) continue;//已经确定了距离的不再访问
dist.put(node,d);
if(map.containsKey(node))
for(int[] next:map.get(node))//将邻接点到起点的距离加入优先队列
{ if(!dist.containsKey(next[0]));
{
priorityQueue.offer(new int[]{d+next[1],next[0]});}}
}if(dist.size()!=N) return -1;
int cnt=0;
for(int c:dist.values())
{
cnt= Math.max(c,cnt);}
return cnt;
}