luogu结题报告:P1260工程规划【样例错坑死爹】【图论/差分约束系统】

来源:互联网 发布:淘宝手机端的收藏链接 编辑:程序博客网 时间:2024/06/10 02:30

题目见:https://www.luogu.org/problem/show?pid=1260

分析

首先声明这个题的样例1是错的,而且题目叙述中要加一句:满足所有不等式的前提下,使工程尽早完成。

这个题表述很直白了,就是给定若干不等式,求一个可行解,然后规定最早开始的量为0。但我以前对差分约束系统了解不多,查了一些资料才搞懂:

给定不等式组TiTjbkbk为已知的常数。设一开始所有变量的取值范围都是(,+),变量取值区间为[low, hith]。不难发现不等式有两个变形:

  1. TiTj+bkTilow{Tj}+bk
  2. TjTibkTjhigh{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;}
0 0
原创粉丝点击