分析
首先声明这个题的样例1是错的,而且题目叙述中要加一句:满足所有不等式的前提下,使工程尽早完成。
这个题表述很直白了,就是给定若干不等式,求一个可行解,然后规定最早开始的量为0。但我以前对差分约束系统了解不多,查了一些资料才搞懂:
给定不等式组 Ti−Tj≤bk,bk 为已知的常数。设一开始所有变量的取值范围都是 (−∞,+∞) ,变量取值区间为[low, hith]。不难发现不等式有两个变形:
-
Ti≤Tj+bk⟺Ti≤low{Tj}+bk
-
Tj≥Ti−bk⟺Tj≥high{Ti}+bk
这样只需要不断地收紧所有变量的取值范围,直到所有变量均无法收紧,系统运行结束。如果出现high < low,则不等式无解。
示例代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
using namespace std;
int from[5005], to[5005], dis[5005];
int n, m;
int high[5005], low[5005];
int main()
{
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> from[i] >> to[i] >> dis[i];
}
for (int i = 1; i <= n; i++) {
high[i] = 100000;
low[i] = -100000;
}
high[1] = low[1] = 0;
int can = 0;
while (1) {
int flag = 0, f = 0;
for (int i = 1; i <= m; i++) {
int x = from[i], y = to[i], b = dis[i];
//printf("%d %d %d \n", x, y, b);
if (high[x] > high[y]+b) {
high[x] = high[y]+b;
f++;
}
if (low[y] < low[x]-b) {
low[y] = low[x]-b;
f++;
}
}
for (int i = 1; i <= n; i++)
if (high[i] < low[i]) {
flag = 1;
break;
}
if (flag) break;
if (f == 0) {
can = 1;
break;
}
/*for (int i = 1; i <= n; i++)
cout << high[i] << ' ' << low[i] << endl;
puts("---------");
cin.get();*/
}
if (!can) {
printf("NO SOLUTION\n");
return 0;
}
int minn = 0x3f3f3f3f;
for (int i = 1; i <= n; i++)
minn = min(minn, low[i]);
for (int i = 1; i <= n; i++)
cout << low[i]-minn << endl;
return 0;
}