UVa 515 - King

Summary
A sequence of integers $$(x_1, x_2, \dots, x_n)$$ must satisfy a set of given constraints of the form: $$\sum_{j=s_i}^{s_i+n_i} x_j R_i k_i$$ (where $$R_i$$ is one of the relations: <, >), for i=1..m.

The question is: does such a sequence exist?

Explanation
First of all, simply the constraints. Consider a function $$S(k) = \sum_{i=1}^k x_i$$, $$S(0)=0$$.

With this function, the constraints can be rewritten as: $$[S(s_i+n_i)-S(s_i-1)] R_i k_i$$.

Furthermore, it's clear that the sequence $$(x_1, x_2, \dots, x_n)$$ exists if and only if a sequence of integers $$(S(1), S(2), \dots, S(n))$$, satisfying the constraints in the above form exists.

The next step is to get rid of the strict inequalities. A contraint $$a < b$$ is equivalent to $$a \le b-1$$ in integers.

Similarly, $$a > b$$ is the same thing as $$a \ge b+1$$, or alternatively $$-a \le -b-1$$.

We are left with a system of equations of the form: $$S(a_i) - S(b_i) \le c_i$$, where all $$a_i,b_i,c_i$$ are integers, and $$0 \le a_i,b_i \le n$$.

A system like this one is known as a system of difference constraints. In order to solve it, first construct a constraint graph, whose vertices are labelled with numbers from 0 to $$n$$, and each constraint corresponds to an edge from vertex $$b_i$$ to vertex $$a_i$$ of weight $$c_i$$. Also, the graph has a special vertex $$s$$, and edges of weight 0 from $$s$$ to every other vertex.

It is known that a system of difference constrains has a solution in integers, if and only if the corresponding constraint graph has no negative cycles, and all $$c_i$$ are integers.

Implementation
A compact implementation of the above idea follows. It uses Bellman-Ford algorithm to detect negative cycles.


 * 1) include 

int X[1024], Y[1024], Z[1024], D[1024], M, m, n, x, y, z, i; char s[8]; void E(int x, int y, int z) { X[M]=x; Y[M]=y; Z[M++]=z; }

int main { while (scanf("%d %d",&n,&m)==2 && n>0) { for (n+=2, M=0; m-- && scanf("%d %d %s %d", &x,&y,s,&z)==4;) s[0]=='g' ? E(x+y+1,x,-z-1) : E(x,x+y+1,z-1); for (i=1; iD[X[i]]+Z[i]) z++, D[Y[i]]=D[X[i]]+Z[i]; while (z && x++<n); printf(z ? "successful conspiracy\n" : "lamentable kingdom\n"); } return 0; }

Input
4 2 1 2 gt 0 2 2 lt 2 1 2 1 0 gt 0 1 0 lt 0 0

Output
lamentable kingdom successful conspiracy