力扣---网络延迟时间---迪杰斯特拉,弗洛伊德floyd

首先推荐博客:图论最短路径专题(力扣743、5888)_力扣 最短路径-CSDN博客 

迪杰斯特拉算法:

太久没有做图论的题了,,临时抱佛脚。。

这道题可以转化为max{点x到点k的距离}。因为带权图(权值为正),无环,求最短路径的情况,迪杰斯特拉分为两个步骤:首先是初始化数组(G:二维数组,记录初始时刻点与点之间的距离,dist:每个点距k点的距离,visit:每个点是否已经确认距k点的距离)。第二部是一个大循环,即将n个点全部更新距k点的距离。再循环中,分为三个小步骤:第一点是寻找距k点距离最短的点(且该点距离k的距离还没有确定),第二点是将该点放入已知距k点距离的集合内(即visit[jj]=1),第三点是更新jj临近的那些点(距离k的距离还没有确定)距离k点的值。

参考PPT:

代码:

C++:

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int n, int k) {
        int inf=INT_MAX;
        vector<vector<int>> G(n+1,vector<int>(n+1,inf));
        vector<int> dist(n+1,inf);//k距离其他结点的距离
        vector<int> visit(n+1,0);//结点x是否已经确定最短距离
        int res=0;
        /*初始化*/
        int len=times.size();
        for(int i=0;i<len;i++){
            G[times[i][0]][times[i][1]]=times[i][2];
        }
        for(int i=1;i<=n;i++){
            G[i][i]=0;
        }
        dist[k]=0;

        
        /*正式迪杰斯特拉*/ //要更新n个结点
        for(int i=1;i<=n;i++){
            int min=INT_MAX;
            int jj=-1;
            /*找到距离k最短的距离*/
            for(int j=1;j<=n;j++){
                if(visit[j]==0 && dist[j]<min){
                    jj=j;
                    min=dist[j];
                }
            }
            /*visit[]*/
            if(jj==-1){return -1;}
            visit[jj]=1;
            res=max(res,min);
            /*更新以jj为头结点的距离*/
            for(int j=1;j<=n;j++){
                if(G[jj][j]!=INT_MAX && visit[j]==0 && dist[j]>dist[jj]+G[jj][j]){
                    dist[j]=dist[jj]+G[jj][j];
                }
            }
        }
        return res;
    }
};

Python:

class Solution:
    def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
        G=[[float("inf") for _ in range(n+1)] for _ in range(n+1)]
        dist=[float("inf")]*(n+1)
        visit=[0]*(n+1)
        res=0
        len_=len(times)
        for i in range(len_):
            G[times[i][0]][times[i][1]]=times[i][2]

        for i in range(1,n+1):
            G[i][i]=0

        dist[k]=0

        for i in range(1,n+1):
            min_=float("inf")
            jj=-1
            for j in range(1,n+1):
                if visit[j]==0 and dist[j]<min_:
                    jj=j
                    min_=dist[j]

            if jj==-1:
                return -1
            visit[jj]=1
            res=max(res,min_)

            for j in range(1,n+1):
                if G[jj][j]!=float("inf") and visit[j]==0 and dist[j]>dist[jj]+G[jj][j]:
                    dist[j]=dist[jj]+G[jj][j]
        return res

Floyd算法:

Floyd算法不能有环,允许有带负权值的边,但不允许有包含带负权值的边组成的回路
采用动态规划的思想,用结点k来更新结点i,j之间的距离:G[i][j]=?=G[i][k]+G[k][j],用三层for循环来实现

参考PPT:

代码:

C++:

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int n, int k) {
        int inf=INT_MAX/2;
        vector<vector<int>> G(n+1,vector<int>(n+1,inf));
        /*初始化*/
        int len=times.size();
        for(int i=0;i<len;i++){
            G[times[i][0]][times[i][1]]=times[i][2];
        }
        for(int i=1;i<=n;i++){
            G[i][i]=0;
        }
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    if(G[i][j]>G[i][k]+G[k][j]){
                        G[i][j]=G[i][k]+G[k][j];
                    }
                }
            }
        }

        /*求结果*/
        int res=0;
        for(int i=1;i<=n;i++){
            res=max(res,G[k][i]);
        }
        if(res==INT_MAX/2){return -1;}
        return res;
    }
};

Python:

class Solution:
    def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
        G=[[float("inf") for _ in range(n+1)] for _ in range(n+1)]
        
        len_=len(times)
        for i in range(len_):
            G[times[i][0]][times[i][1]]=times[i][2]

        for i in range(1,n+1):
            G[i][i]=0

        for kk in range(1,n+1):
            for i in range(1,n+1):
                for j in range(1,n+1):
                    if G[i][j]>G[i][kk]+G[kk][j]:
                        G[i][j]=G[i][kk]+G[kk][j]
        res=0
        for i in range(1,n+1):
            res=max(res,G[k][i])
        if res==float("inf"):
            return -1
        return res

注意是,应该是:(不要用k哦)

for kk in range(1,n+1)

Bellman Ford算法:

该算法用于在带权图中(可以有负权边)找到从单一源点到所有其他顶点的最短路径,也可以检测是否有负权环
检测负环的原理基于这样一个事实:在一个包含n个顶点的图中,任何两个顶点之间的最短路径最多包含n-1条边。因此,Bellman-Ford算法的基本步骤包括对所有边重复进行n-1次松弛操作。松弛操作即:

if(res[a]!=INT_MAX && res[a]+w<res[b]){
    res[b]=res[a]+w;
}

代码:

C++:

class Solution {
public:
    int networkDelayTime(vector<vector<int>>& times, int n, int k) {
        vector<int> res(n+1,INT_MAX);
        res[k]=0;
        int len=times.size();
        /*n-1次松弛操作*/
        for(int i=1;i<=n-1;i++){
            for(int j=0;j<len;j++){
                int a=times[j][0];
                int b=times[j][1];
                int w=times[j][2];
                if(res[a]!=INT_MAX && res[a]+w<res[b]){
                    res[b]=res[a]+w;
                }
            }
        }
        int fin=0;
        for(int i=1;i<=n;i++){
            fin=max(fin,res[i]);
        }
        if(fin==INT_MAX){return -1;}
        return fin;
    }
};

Python:

class Solution:
    def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
        res=[0x3f3f3f3f]*(n+1)
        res[k]=0
        len_=len(times)

        for i in range(1,n):
            for j in range(len_):
                a=times[j][0]
                b=times[j][1]
                w=times[j][2]
                if res[a]!=0x3f3f3f3f and res[a]+w<res[b]:
                    res[b]=res[a]+w
        fin=0
        for i in range(1,n+1):
            fin=max(fin,res[i])
        if fin==0x3f3f3f3f:
            return -1
        return fin

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值