Differential constraint
Problem type description
 given n n n variables and m m m constraints, e.g x i − x j ≤ c k x_ix_j\leq c_k xi − xj ≤ ck, let you find a set of solutions. Yes, all constraints are satisfied.
Model transformation

Deform: x i ≤ x j + c k x_i\leq x_j + c_k xi≤xj+ck
 Easy to find, with the most short circuit d i s [ v ] ≤ d i s [ u ] + w dis[v]\leq dis[u]+w dis[v] ≤ dis[u]+w is very similar

How to understand?

If u u u and v v There is a connecting edge between v, then d i v [ v ] div[v] The value of div[v], do you want it = = d i s [ u ] + w ==dis[u]+w ==dis[u]+w, yes < d i s [ u ] + w <dis[u]+w <dis[u]+w
Because where is the connecting edge, it can be relaxed as long as it is d i s [ v ] > d i s [ u ] + w dis[v]>dis[u]+w Dis [v] > dis [u] + W, then this situation can be relaxed


Then we transform the inequality problem into a shortest path problem
Progressive thinking

Next, our x [ 1 − n ] x[1n] x[1 − n] is equivalent to d i s [ 1 − n ] dis[1n] dis[1 − n], and then what we want to solve is d i s [ 1 − n ] dis[1n] dis[1 − n], that is to solve the shortest path

As long as there is a directed edge, it satisfies the condition of that inequality and runs the shortest path to find all the shortest distances d i s [ ] dis[~] dis []
How to select the source point?

Because it is a directed graph, we need to traverse all nodes, so we need to establish a super source point No. 0
 We selected a "relationship", so the overall offset is a value, and the answer is still correct
 All nodes to 0 0 The distance of 0 is a fixed value d d d. General blogs are set to 0 0 0, of course, you change to 114514 114514 There is no difference in 114514
 After all, it's just an offset
There is no solution to the inequality system

Under what circumstances does the above polynomial group have no solution?

In our transformed model, if the shortest distance of a point d i s [ i ] dis[i] dis[i] does not exist, that is, non negative infinity  > there is a negative ring
In the original equations, several variables are constrained each other

Therefore, we can use SPFA to judge the negative ring, that is, there is num [i] > n
Why not use Dijkstra
 Dijkstra cannot handle negative edge weights. It has been established d i s [ ] dis[] If the point of dis [] has negative edge weight, it may be updated by subsequent points.
expand

The form of the title is x i − x j ≤ c k x_ix_j\le c_k xi−xj≤ck

if it is x i − x j ≥ c k x_ix_j\ge c_k xi−xj≥ck
 Then multiply both sides by the minus sign at the same time, with x j − x i ≤ c k x_jx_i\le c_k xj−xi≤ck

if it is x i − x j = c k x_ix_j=c_k xi − xj = ck, that is, the unity of the above two
 $x_ix_j\le c_k And And And x_jx_i\leq c_k $, twoway edges can be established
code implementation
#include <bits/stdc++.h> #include <bits/extc++.h> #include <unordered_map> #include <unordered_set> using namespace std; using namespace __gnu_cxx; using namespace __gnu_pbds; #define debug(x) cerr << #x << ": " << x << '\n'; #define bd cerr << "" << el; #define el '\n' #define cl putchar('\n'); #define pb push_back #define eb emplace_back #define x first #define y second #define rep(i, a, b) for (int i = (a); i <= (b); i++) #define lop(i, a, b) for (int i = (a); i < (b); i++) #define dwn(i, a, b) for (int i = (a); i >= (b); i) #define ceil(a, b) (a + (b  1)) / b #define ms(a, x) memset(a, x, sizeof(a)) #define INF 0x3f3f3f3f #define db double #define all(x) x.begin(),x.end() #define cmax(a, b) a = max(a, b) #define cmin(a, b) a = min(a, b) #define reps(i, x) for (int i = 0; i < x.size(); i++) typedef long long LL; typedef long double LD; typedef pair<int, int> PII; typedef pair<db, db> PDD; typedef vector<int> vci; template <typename T> inline void read(T &x) { x = 0; T f = 1; char c = getchar(); while (!isdigit(c)) { if(c == '') f = 1; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } x *= f; } const int N = 1e5 + 10, M = 2e6 + 10, B = 66, md = 1e9 + 7; const double PI = acos(1), eps = 1e8; int T, n, m; vector<PII> g[N]; int vis[N], dis[N]; bool inq[N]; int main() { read(n), read(m); queue<int> q; rep(i, 1, m) { int u, v, w; read(v), read(u), read(w); g[u].pb({v, w}); } rep(i, 1, n) { g[0].pb({i, 0}); //Establish an edge from 0 to all points //This 0 is just an offset. You can change it to any value } memset(dis, 0x3f, sizeof dis); dis[0] = 0; q.push(0); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] ++ ; inq[u] = false; if(vis[u] > n + 1) { cout << "NO"; exit(0); } #define v g[u][i].first #define w g[u][i].second reps(i, g[u]) { if (dis[v] > dis[u] + w) { dis[v] = dis[u] + w; if(!inq[v]) { inq[v] = true; q.push(v); } } } #undef v #undef w } rep(i, 1, n) { cout << dis[i]; if( i < n) cout << ' '; } }