码迷,mamicode.com
首页 > 其他好文 > 详细

负环与差分约束

时间:2020-01-22 21:48:27      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:最短路   front   span   head   ret   false   lan   约束   超级   

判负环

\(SPFA\)时,设\(sp\_cnt[x]\)表示从\(x\)入队次数,若更新时, \(sp\_cnt[y]\gt n\) ,则说明图中有负环,算法正常结束,则图中无负环

bool spfa()
{
    queue<int> q;
    dis[1]=0;
    vis[1]=true;
    q.push(1);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        vis[x]=false;
        if(++sp_cnt[x]>n) return true;
        for(int i=head[x];i;i=e[i].nxt)
        {
            int y=e[i].to,v=e[i].v;
            if(dis[y]>dis[x]+v)
            {
                dis[y]=dis[x]+v;
                if(!vis[y])
                {
                    q.push(y);
                    vis[y]=true;
                }
            }
        }
    }
    return false;
}

差分约束

差分约束系统即为\(n\)元一次不等式组,每个约束条件都是由两个变量作差构成的,形如\(x_i-x_i \leqslant c_k\),目标为求出一组解可以满足所有约束条件

\(x_i-x_j \leqslant c_k\)可变形为\(x_i \leqslant x_j+c_k\),与最短路中三角形不等式\(dis[y] \leqslant dis[x]+v\)相似,于是将不等式组中的变量看作点,每个约束条件\(x_i-x_j \leqslant c_k\)为从节点\(i\)向节点\(j\)连一条边权为\(c_k\)的有向边

在跑完最短路后,\(x_i=dis[i]\)为差分约束系统中的一组解,若存在负环和终点不可达时,无解

\(x_i-x_j \geqslant c_k\)变形为\(x_j-x_i \leqslant -c_k\)

\(x_i-x_j < c_k\)变形为\(x_i-x_j \leqslant c_k-1\)

\(x_i-x_j > c_k\)变形为\(x_i-x_j \geqslant c_k+1\)

\(x_i-x_j = c_k\)变形为\(x_i-x_j \leqslant 0\\)\(\ x_i-x_j \geqslant 0\)

必要时,建一个超级源点

负环与差分约束

标签:最短路   front   span   head   ret   false   lan   约束   超级   

原文地址:https://www.cnblogs.com/lhm-/p/12229479.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!