• 【最短路/线性差分约束】Layout POJ


    Layout POJ - 3169

    题意:

    (n)头奶牛按序号(1~n)排成一行,允许多头奶牛站在同一个位置上。给定(ML)行关系,每行三个整数(u,v,dis),表示奶牛(u)与奶牛(v)的距离不大于(dis);再给定(MD)行关系,每行三个整数(u,v,dis),表示奶牛(u)与奶牛(v)的距离不小于(dis)。求奶牛(n)与奶牛(1)最大可能距离

    如果最大可能距离不存在,输出(-1);如果最大可能距离可以是任意值,输出(-2);否则输出这个距离。

    思路:

    线性差分约束,所求的是最大值。因此答案就是从节点(1)到节点(n)最短路

    所给出的约束关系都应该为(u-v≤d)的形式。

    对于其中(MD)行约束关系,给出的是(u-v≥d),因此等号两边同乘(-1)变形得(v-u≤-d)

    由此可见根据约束关系所建的图包含负权边,即可能存在负权环,对应的是最大可能距离不存在的情况;如果奶牛(n)与奶牛(1)之间没有直接或间接的约束关系,也就是节点(n)不可到达,对应的是最大可能距离可以是任意值的情况。

    const int INF = 0x3f3f3f3f3f;
    const int maxn = 1000 + 10;
    
    int num = 0;
    int n, m;
    int head[maxn], inq_cnt[maxn];
    LL d[maxn];
    bool inq[maxn];
    
    struct Edge {
        int next, to;
        LL dis;
    }edges[maxn*20];
    
    void add_edge(int from, int to, LL dis) {
        num++;
        edges[num].next = head[from];
        edges[num].to = to;
        edges[num].dis = dis;
        head[from] = num;
    }
    
    bool spfa(int s) {
        queue<int> q;
        d[s] = 0;
        inq[s] = true;
        q.push(s);
        inq_cnt[s]++;
        while (!q.empty()) {
            int u = q.front(); q.pop();
            inq[u] = false;
            for (int i = head[u]; i != 0; i = edges[i].next) {
                Edge& e = edges[i];
                if (d[u] < INF && d[u] + e.dis < d[e.to]) {
                    d[e.to] = d[u] + e.dis;
                    if (!inq[e.to]) {
                        if (inq_cnt[e.to] > n) return false;
                        q.push(e.to);
                        inq[e.to] = true;
                        inq_cnt[e.to]++;
                    }
                }
            }
        }
        return true;
    }
    
    void init() {
        num = 0;
        memset(edges, 0, sizeof(edges));
        memset(inq_cnt, 0, sizeof(inq_cnt));
        memset(inq, false, sizeof(inq));
        memset(head, 0, sizeof(head));
        for (int i = 0; i <= n; i++) d[i] = INF;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
      //  FILE* stream1;
      //  freopen_s(&stream1, "input.txt", "r", stdin);
      //  freopen_s(&stream1, "output.txt", "w", stdout);
       // int t; cin >> t; for(int kase=1;kase<=t;kase++) {
        int ml, md;
        cin >> n >> ml >> md;
        init();
        for (int i = 1; i <= ml; i++) {
            int u, v;
            LL dis;
            cin >> u >> v >> dis;
            //v-u<=dis;
            add_edge(u, v, dis);
           // printf("%d→%d:%lld
    ", u, v, dis);
        }
        for (int i = 1; i <= md; i++) {
            int u, v;
            LL dis;
            cin >> u >> v >> dis;
            //v-u>=dis
            //u-v<=-dis
            add_edge(v, u, -dis);
          //  printf("%d→%d:%lld
    ", v, u, -dis);
        }
    
        if (!spfa(1)) cout << "-1";
        else {
            if (d[n] == INF) cout << "-2";
            else cout << d[n] - d[1];
        }
       // }
        return 0;
    }
    
  • 相关阅读:
    生成函数初步
    Lg 8月赛(构造+交互)
    wqs 二分学习笔记
    FastAPI 学习之路(十六)Form表单
    线性代数入门
    Oracle-PDB拔插
    MySQL-audit审计插件
    MySQL-用户与权限管理
    MySQL-存储引擎
    MySQL-逻辑结构
  • 原文地址:https://www.cnblogs.com/streamazure/p/13419903.html
Copyright © 2020-2023  润新知