POJ 3169 Layout(差分约束基础)

来源:互联网 发布:linux 复制目录及文件 编辑:程序博客网 时间:2024/06/10 01:15

题意:
。。。
思路:
1)不等式
题目中有两类不等式,b-a<=c 和 b - a >= c ( id(a)<id(b) )
把后者换成a-b<=-c,然后求从1开始的最短路。如果d[n]=inf, 则说明(1, n)不存在小于等于的约束关系。
2) 判负环
因为1可能到不了负环,所以首先要把全部节点入队,然后跑一遍spfa来判断。

struct Edge{    int nxt, cost, to;    Edge ():nxt(0) {}    Edge(int x, int y, int z):nxt(x), cost(y), to(z){}};int h[Maxn+5], d[Maxn+5], used[Maxn+5], cnt[Maxn+5], tot, n;Edge E[30000];void add_edge(int from, int to, int cost) {    //debug    //printf("add_edge: from %d to %d cost %d\n", from, to, cost);    E[tot] = Edge(h[from], cost, to);    h[from] = tot++;}int check() {    fill(d+1, d+n+1, 0);    memset(used, 0, sizeof(used));    memset(cnt, 0, sizeof(cnt));    queue<int> q;    rep(i, 1, n) {        q.push(i);d[i]=0;used[i]=1;    }    while (!q.empty()) {        int fr=q.front();q.pop();        used[fr] = 0;        // debug        //printf("pick %d\n", fr);        for (int i=h[fr];i;) {            Edge &e = E[i];            if (d[fr]+e.cost < d[e.to]) {                // debug                //printf("upd %d from %d to %d\n", e.to, d[e.to], d[fr]+e.cost);                if (!used[e.to]) {                    // debug                    //printf("pb %d\n", e.to);                    q.push(e.to);                    used[e.to]=1;                }                d[e.to] = d[fr]+e.cost;                if (++cnt[e.to] >= n) return 0;            }            i = e.nxt;        }    }    return 1;}void go(int st) {    fill(d+1, d+n+1, inf);    memset(used, 0, sizeof(used));    queue<int> q;    q.push(st);d[st] = 0;used[st] = 1;    while (!q.empty()) {        int fr=q.front();q.pop();        used[fr] = 0;        // debug        //printf("pick %d\n", fr);        for (int i=h[fr];i;) {            Edge &e = E[i];            if (d[fr]+e.cost < d[e.to]) {                // debug                //printf("upd %d from %d to %d\n", e.to, d[e.to], d[fr]+e.cost);                if (!used[e.to]) {                    // debug                    //printf("pb %d\n", e.to);                    q.push(e.to);                    used[e.to]=1;                }                d[e.to] = d[fr]+e.cost;            }            i = e.nxt;        }    }}int solve() {    if (!check()) return -1;    go(1);    if (d[n] == inf) return -2;    return abs(d[n]);}int main() {#ifndef ONLINE_JUDGE    freopen("input.in", "r", stdin);#endif    //SPEED_UP    int ml, md;    scanf("%d%d%d", &n, &ml, &md);    int aa, bb, cc;    tot = 1;    // "b-a<=c"    rep(i, 1, ml) {        scanf("%d%d%d", &aa, &bb, &cc);        add_edge(aa, bb, cc);    }    // "b-a>=c" => "a-b<=-c"    rep(i, 1, md) {        scanf("%d%d%d", &aa, &bb, &cc);        add_edge(bb, aa, -cc);    }    // 隐含的顺序关系,不用约束也可以,数据已经保证了    rep(i, 2, n) add_edge(i, i-1, 0);    printf("%d\n", solve());    return 0;}
0 0