POJ - 3169 -- Layout

版权声明: https://blog.csdn.net/moon_sky1999/article/details/81950786

题目来源:http://poj.org/problem?id=3169

思路来自:https://blog.csdn.net/mengxiang000000/article/details/52613328

差分约束系统题目。题目要求即是求出an-a1的最大值。

如果只考虑ml的情况,则可以推出:

a1-a2<=k1;  --  1

a2-a3<=k2;  --  2

a1-a3<=k3;  --  3

1.2式可以推得a1-a3<=k1+k2

由此a1-a3<=min(k1+k2,k3).

对于md的情况:

a1-a2>=k1可以转化为a2-a1<=-k1.因此可以转化为上一种的形式。

最短路可以用spfa求出。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>

#define ll long long
#define ull unsigned long long
#define BUG printf("************\n")
#define STOP getchar()
using namespace std;

const int mod = 1e9 + 7;
const int maxn = 1e3 + 10;
const int maxm = 1e4 + 10;
const double eps = 1e-8;

ll gcd(ll a,ll b) {
    return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a,ll b) {
    return a / gcd(a, b) * b;
}

struct edge {
    int to, next, vi;
} e[maxn * maxn];
int n, ml, md, cnt, head[maxn], dis[maxn], g[maxn][maxn], inq[maxn];
bool vis[maxn];
queue<int> q;
void ins(int x,int y,int z) {
    e[++cnt].to = y;
    e[cnt].next = head[x];
    e[cnt].vi = z;
    head[x] = cnt;
}
int main() {
/*
    freopen("equal.in", "r", stdin);
    freopen("equal.out", "w", stdout);
*/
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    while (cin >> n >> ml >> md) {
        cnt = 0;
        memset(head, 0, sizeof(head));
        memset(g, 63, sizeof(g));
        int x, y, z;
        for (int i = 1; i <= ml; ++i) {
            cin >> x >> y >> z;
            g[x][y] = min(g[x][y], z);
        }
        for (int i = 1; i <= md; ++i) {
            cin >> x >> y >> z;
            g[y][x] = min(g[y][x], -z);
        }
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (g[i][j] < 1e8) {
                    ins(i, j, g[i][j]);
                }
            }
        }
        memset(dis, 63, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        memset(inq, 0, sizeof(inq));
        while (!q.empty())q.pop();
        bool ok = 1;
        q.push(1);
        vis[1] = 1;
        dis[1] = 0;
        inq[1]++;
        while (!q.empty()) {
            int x = q.front();
            q.pop();
            for (int i = head[x]; i; i = e[i].next) {
                int v = e[i].to;
                if (dis[v] > dis[x] + e[i].vi) {
                    dis[v] = dis[x] + e[i].vi;
                    if (vis[v] == 0) {
                        vis[v] = 1;
                        q.push(v);
                        inq[v]++;
                    }
                    if (inq[v] > n) {
                        ok = 0;
                        break;
                    }
                }
            }
            if (!ok)break;
            vis[x] = 0;
        }
        if (!ok)cout << -1 << endl;
        else if (dis[n] > 1e8)cout << -2 << endl;
        else cout << dis[n] << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/moon_sky1999/article/details/81950786
今日推荐