Dijkstra算法==>SPFA

这是一个贪心算法,而不是一个动态规划算法

1.这是一个从局部最优到全局最优的方法
2.如果 3->5->4->1是一个最优路径(路径权值最小),3->5->4一定是一个最优路径,3->5一定是最优路径
3.这里所说的3->5->4是一个最优路径的内涵是: 3->...->4都不会优于3->5->4
4.3->5->4优于3->4的过程是:
  先记录3->53->4
  由于5的广度优先搜索中存在5->4这条路径
  计算5->4 + 3->5 的和小于 3->4, 所以剪枝掉3->4的所有路径,因为3->4->x都可以用3->5->4->x来代替
5.distance[toIndex]记录的都是从rootIndex->...->toIndex的最短路径
6.如果rootIndex->...->toIndex还存在最短路径,即 distance[toIndex] < distance[fromIndex] + distance[fromIndex->toIndex],则需要重新搜索toIndex的邻接节点,因为这意味着rootIndex到这些节点的路径值都需要被更新
  例子: 假设rootIndex = 3, distance[4] = 10. 即如果原来从3->2->4=10
        4的邻接节点有5,1,6,即 distance[5] = rootIndex->2->4->5 = 10 + distance[4->5]
        但是,如果通过寻找发现 3->1->7->4=9,意味着从rootIndex到4的所有邻接节点的距离都需要更新
        所以以下代码中: 
        distance[temps[i]] = distance[temp] + graph[temp][temps[i]];是为了更新当前的toIndex节点
        而Q.push(temps[i]);是为了重新更新toIndex的所有邻接节点
        
#define INF INT_MAX / 2
class Solution {
public:
    void Show(vector<int>& v) {
        for(int i = 0; i < v.size(); i++) {
            cout << i << " 的值为: " << v[i] << "   ";
        }
        cout << endl;
    }

    vector<int> linkNode(int fromIndex, vector<vector<int>> graph) {
        vector<int> ret;
        for(int i = 1; i < graph.size(); i++) {
            if(graph[fromIndex][i] != INF) ret.push_back(i);
        }
        return ret;
    }
    int networkDelayTime(vector<vector<int>>& times, int n, int k) {
        /**
            1.Dijkstra算法
            2.起点为第k个节点,
            3.更新三个数组: visited, distance, parent
            4.==>
            更新visited的操作是:以该节点为root查找该节点到其下一个节点的距离时, visited[rootIndex] = true
            更新distance的操作是: distance[t] = min(Distance(rootIndex, t) + ... + 一直加到根节点, distance(t))
            更新parent的操作是: parent[t] 根据distance更新: 保持不变和更新为rootIndex
         */
        //注意: 0节点不用
        vector<int> visited(n + 1, 0);
        vector<int> distance(n + 1, INF);
        vector<int> parent(n + 1, -1);
        //构件图:
        vector<vector<int>> graph(n + 1, vector<int>(n + 1, INF));
        for(int i = 0; i < times.size(); i++) {
            graph[times[i][0]][times[i][1]] = times[i][2];
        }
        /**
               1  2  3  4
            1 -1 -1 -1 -1
            2  1 -1  1 -1
            3 -1 -1 -1  1
            4 -1 -1 -1 -1
         */
        //广度优先搜索
        queue<int> Q;
        Q.push(k);
        distance[k] = 0;
        parent[k] = -1;
        while(!Q.empty()) {
            int temp = Q.front();
            Q.pop();
            vector<int> temps = linkNode(temp, graph);
            for(int i = 0; i < temps.size(); i++) {
                if(distance[temp] + graph[temp][temps[i]] < distance[temps[i]]) {
                    distance[temps[i]] = distance[temp] + graph[temp][temps[i]];
                    Q.push(temps[i]);
                }
            }
        }
        int maxn = -1;
        for(int i = 1; i < n + 1; i++) {
            if(maxn < distance[i]) {
                maxn = distance[i];
            }
        }
        return maxn >= INF ? -1 : maxn;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值