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

题目见: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;
}

转载于:https://www.cnblogs.com/ljt12138/p/6684365.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值