zoukankan      html  css  js  c++  java
  • 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 
    ", 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
    ");
            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;
    }
    
  • 相关阅读:
    HDU5873
    HDU5874
    HDU1565(状态压缩dp)
    POJ2774(二分+哈希)
    HDU4474
    HDU2602(背包)
    单链表
    POJ2503(hash)
    POJ1200(hash)
    顺序表
  • 原文地址:https://www.cnblogs.com/ljt12138/p/6684365.html
Copyright © 2011-2022 走看看