Skip to content

差分约束系统

2021-06-13

简介

给定差分不等式组

{X1X21X3X23X4X12

求一组满足所有条件的 X1Xn 的解。

以上形式的不等式组称作「差分约束系统」。

原理

根据 松弛操作 原理,当 SPFA 结束时,图中任意两个节点 i,j 满足

\dis[j]\dis[i]+g[i,j]

事实上,差分约束系统的不等式可以变形为

XjXi+C

于是令 \dis[j]=Xj,\dis[i]=Xi,g[i,j]=C

在图上跑一遍 SPFA 后,X1Xn 便满足差分不等式组。

模板

cpp
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;
                }
            }
        }
    }
}