POJ 1201 Intervals 差分约束

http://poj.org/problem?id=1201

TLE了很久,因为用了cin.....

思路和其他差分约束差不多,http://www.cppblog.com/menjitianya/archive/2015/11/19/212292.html

如果区间[a, b]中至少有c个元素,如果用上面的博客,那么说明xa - xb >= c,但是注意这里是闭区间,xa - xb是不包括b这个点的,

就比如用了[a, b]有c个元素,[b, d]有x个,那么ans = c + x - 1个,因为有一个点是重合了的。

为了解决这个问题,重新定义,令xa - x(b+1) >= c代表区间[a, b]拥有的数量,其实这是显然的,只不过刚开始习惯用xa - xb代表[a, b]

没想到-xb是不包括b的。

这里还有一个问题就是区间不连续,所以跑不了最长路的问题。

[1, 4] >= 2      [6, 7] >= 2

无法跑spfa

所以要加边:

[3, 3]拥有的数量是 >= 0    <= 1的,

所以

x3 - x4 >= 0

x3 - x4 <= 1

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
#include <time.h>
#include <iomanip>
const int maxn = 2e5 + 20;
struct Edge {
    int u, v, w, tonext;
}e[maxn * 2];
int num, first[maxn];
void addEdge(int u, int v, int w) {
    ++num;
    e[num].u = u, e[num].v = v, e[num].w = w, e[num].tonext = first[u];
    first[u] = num;
}
queue<int> que;
int in[maxn], dis[maxn], tim[maxn];
bool spfa(int bx, int n) { //从bx开始,有n个顶点
    for (int i = 1; i <= n; ++i) {
        dis[i] = inf;
        tim[i] = 0; //入队次数清0
        in[i] = false; //当前这个节点不在队列里
    }
    while (!que.empty()) que.pop();
    que.push(bx), in[bx] = true, dis[bx] = 0, tim[bx]++;
    while (!que.empty()) {
        int u = que.front();
        if (tim[u] > n) return true; //入队次数超过n次,出现负环
        que.pop();   //in[u] = false ?
        for (int i = first[u]; i; i = e[i].tonext) {
            if (dis[e[i].v] > dis[e[i].u] + e[i].w) {
                dis[e[i].v] = dis[e[i].u] + e[i].w;
                if (!in[e[i].v]) { //不在队列
                    que.push(e[i].v);
                    in[e[i].v] = true;
                    tim[e[i].v]++;
                }
            }
        }
        in[u] = false;
    }
    return false;
}

void work() {
//    memset(first, -1, sizeof first);
    int n;
    cin >> n;
    int mx = 0;
    for (int i = 1; i <= n; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
//        if (u > v) swap(u, v);
        ++u; ++v;
        ++v;
        mx = max(mx, v);
        addEdge(u, v, -w);

    }
    for (int i = 1; i < mx; ++i) {
        addEdge(i, i + 1, 0);
        addEdge(i + 1, i, 1);
    }
    spfa(1, mx);
//    cout << spfa(1, mx) << endl;
    cout << -dis[mx] << endl;
//    printf("%d
", -dis[mx + 1]);
}

int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    IOS;
    work();
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7163654.html