负环与差分约束

判负环

\(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\)为从节点\(j\)向节点\(i\)连一条边权为\(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\)

必要时,建一个超级源点

求解最大解用最短路,求解最小解用最长路

posted @ 2020-01-22 20:10  lhm_liu  阅读(237)  评论(0编辑  收藏  举报