【图论】BellmanFord算法
适用于任何权的图,负权也可以做。假如从s出发的子图中存在负环,则算法会报告发现负环,否则会正确求出最短路。
松弛操作
一种基于松弛(relax)操作的最短路算法。
第i轮松弛(每条边使用一次)后,从节点s出发的经过<=i条边的到达每个节点的最短路已经找到。假如存在最短路,则最多经过n-1条边。所以假如一条边被松弛了n次,则不存在(从s到达v的)最短路。
BellmanFord算法
队列优化
成功入队的才是相比上一轮松弛有变化的点,其他的点不需要松弛。
返回值表示是否不存在从s出发能到达的负环。
namespace BellmanFord {
    const int MAXN = 2e5 + 10;
    int n;
    vector<pii> G[MAXN];
    ll dis[MAXN];
    int cnt[MAXN];
    bool vis[MAXN];
    queue<int> Q;
    bool bellmanford(int s) {
        fill(dis + 1, dis + 1 + n, LINF);
        fill(cnt + 1, cnt + 1 + n, 0);
        fill(vis + 1, vis + 1 + n, 0);
        while(!Q.empty())
            Q.pop();
        dis[s] = 0;
        vis[s] = 1;
        Q.push(s);
        while(!Q.empty()) {
            int u = Q.front();
            Q.pop();
            vis[u] = 0;
            ++cnt[u];
            if(cnt[u] == n)
                return false;
            for(pii &p : G[u]) {
                int v = p.first;
                int w = p.second;
                if(dis[v] <= dis[u] + w)
                    continue;
                dis[v] = dis[u] + w;
                if(!vis[v]) {
                    vis[v] = 1;
                    Q.push(v);
                }
            }
        }
        return true;
    }
}
乱优化
除了队列优化以外,其他的奇奇怪怪的优化完全不知道其道理何在。
栈优化
这个也是改变了点松弛的顺序,不再满足每一轮松弛原本的定义,所以n轮松弛不一定够(即超过n次松弛仍然可能不是负环),最差复杂度为指数级。
优先队列优化
这个也是改变了点松弛的顺序,不再满足每一轮松弛原本的定义,所以n轮松弛不一定够(即超过n次松弛仍然可能不是负环),最差复杂度为指数级。
LLL优化
将普通队列换成双端队列,每次将入队结点距离和队内距离平均值比较,如果更大则插入至队尾,否则插入队首。
SLF优化
将普通队列换成双端队列,每次将入队结点距离和队首比较,如果更大则插入至队尾,否则插入队首。

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号