差分约束系统
简介 #
给定差分不等式组
$$\begin{cases} X_1 - X_2 ≤ 1\\ X_3 - X_2 ≤ 3\\ X_4 - X_1 ≤ -2\\ \cdots \end{cases}$$
求一组满足所有条件的 $X_1\cdots X_n$ 的解.
以上形式的不等式组称作「差分约束系统」.
原理 #
根据
松弛操作 原理,当
SPFA
程序 结束时,图中任意两个节点 $i,j$ 满足 $\dis[j] ≤ \dis[i] + g[i,j]$.
事实上,差分约束系统的不等式可以变形为
$$X_j ≤ X_i + C$$
于是令 $\dis[j]=X_j,\dis[i]=X_i,g[i,j]=C$.
在图上跑一遍 SPFA
后,$X_1\cdots X_n$ 便满足差分不等式组.
模板 #
bool in[], X[]; // 将 dis[] 换成 X[],便于理解
struct node {
int val, len;
};
vector<int> g[];
void add(int X_j, X_i, C) { // X_j - X_i ≤ C
g[X_i].push_back(node{X_j, C});
}
void spfa(int s) {
memset(in, false, sizeof in);
memset(X, 0x7f, sizeof X);
X[s] = 0;
queue<int> Q;
Q.push(s), in[s] = true;
while(!Q.empty()) {
int u = Q.front();
Q.pop(), in[u] = false;
for(int i = 0; i < (int) g[u].size(); i ++) {
int v = g[u][i].val;
int d = g[u][i].len;
if(X[v] > X[u] + d) {
X[v] = X[u] + d;
if(!in[v]) {
Q.push(v), in[v] = true;
}
}
}
}
}