• poj 3169 Layout


    Description

    Like everyone else, cows like to stand close to their friends when queuing for feed. FJ has N (2 <= N <= 1,000) cows numbered 1..N standing along a straight line waiting for feed. The cows are standing in the same order as they are numbered, and since they can be rather pushy, it is possible that two or more cows can line up at exactly the same location (that is, if we think of each cow as being located at some coordinate on a number line, then it is possible for two or more cows to share the same coordinate).

    Some cows like each other and want to be within a certain distance of each other in line. Some really dislike each other and want to be separated by at least a certain distance. A list of ML (1 <= ML <= 10,000) constraints describes which cows like each other and the maximum distance by which they may be separated; a subsequent list of MD constraints (1 <= MD <= 10,000) tells which cows dislike each other and the minimum distance by which they must be separated.

    Your job is to compute, if possible, the maximum possible distance between cow 1 and cow N that satisfies the distance constraints.

    Input

    Line 1: Three space-separated integers: N, ML, and MD.

    Lines 2..ML+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at most D (1 <= D <= 1,000,000) apart.

    Lines ML+2..ML+MD+1: Each line contains three space-separated positive integers: A, B, and D, with 1 <= A < B <= N. Cows A and B must be at least D (1 <= D <= 1,000,000) apart.

    Output

    Line 1: A single integer. If no line-up is possible, output -1. If cows 1 and N can be arbitrarily far apart, output -2. Otherwise output the greatest possible distance between cows 1 and N.

    Sample Input

    4 2 1
    1 3 10
    2 4 20
    2 3 3

    Sample Output

    27

    Hint

    Explanation of the sample:

    There are 4 cows. Cows #1 and #3 must be no more than 10 units apart, cows #2 and #4 must be no more than 20 units apart, and cows #2 and #3 dislike each other and must be no fewer than 3 units apart.

    The best layout, in terms of coordinates on a number line, is to put cow #1 at 0, cow #2 at 7, cow #3 at 10, and cow #4 at 27.

    Source

     
    第一次听说差分约束这个词,题目的要求是求1~n最长距离,如果说1和n相距甚远(dis[n]无法通过给出的数据进行更新)输出-2,如果没有可能的阵容来排列(存在负环)输出-1.
    构造查分约束系统,对于ml个数据,a和b最大距离是c,即b - a <= c,对于md个数据,a和b最小距离为c,即b - a >= c,转化一下a - b <= -c,这样都转化成两点距离小于等于一个值,不等式左右可以相加,比如d - e <= g,h - d <= -j,左右相加得出h - e <= g - j,然后通过这样,用spfa最短路进行紧缩,同时标记每个点入队次数,如果某个点入队次数>n那就说明存在负环输出-1,如果最后dis[n]的值未发生变化(仍然为inf)就是输出-2。
     
    对于负环的情况,比如给出数据
    3 2 1
    1 2 10
    2 3 10
    1 2 20
    1和2形成负环2- 1 <= 10,1 - 2 <= -20
     
    邻接表spfa代码:
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #define inf 0x3f3f3f3f
    using namespace std;
    typedef pair<int,int> pa;///方便邻接表记录数据
    int dis[1005],visited[1005],inqueue[1005];///dis为1到某个点的最大距离  即 i - 1 <= dis[i]
    int a,b,c;
    vector<pa> v[1005];///邻接表
    int n,ml,md;
    void spfa() {
        queue<int> q;
        q.push(1);
        dis[1] = 0;
        visited[1] = 1;
        inqueue[1] = 1;
        while(!q.empty()) {
            int t = q.front();
            q.pop();
            visited[t] = 0;
            for(int i = 0;i < v[t].size();i ++) {
                if(dis[v[t][i].first] > dis[t] + v[t][i].second) {
                    dis[v[t][i].first] = dis[t] + v[t][i].second;
                    if(visited[v[t][i].first])continue;///如果已经入队就无需再入队
                    if(++ inqueue[v[t][i].first] > n) {
                        dis[n] = -1;///存在负环
                        return;
                    }
                    q.push(v[t][i].first);
                    visited[v[t][i].first] = 1;
                }
            }
        }
        if(dis[n] == inf)dis[n] = -2;///相距甚远
    }
    int main() {
        scanf("%d%d%d",&n,&ml,&md);
        memset(dis,inf,sizeof(dis));
        for(int i = 0;i < ml;i ++) {
            scanf("%d%d%d",&a,&b,&c);
            v[a].push_back(pa(b,c));/// b - a <= c
        }
        for(int i = 0;i < md;i ++) {
            scanf("%d%d%d",&a,&b,&c);
            v[b].push_back(pa(a,-c));/// b - a >= c -> a - b <= -c
        }
        spfa();
        printf("%d",dis[n]);
    }
  • 相关阅读:
    【转】把VS的智能提示快捷键改成Eclipse的习惯
    论文的写作 —— 参考文献的格式
    论文的写作 —— 参考文献的格式
    OpenMP并行编程应用—加速OpenCV图像拼接算法
    计算广告(computational advertising)
    计算广告(computational advertising)
    开源|LightGBM:三天内收获GitHub 1000+ 星
    Logistic Regression 的简单推导
    Logistic Regression 的简单推导
    在电影里走遍中国
  • 原文地址:https://www.cnblogs.com/8023spz/p/9216425.html
Copyright © 2020-2023  润新知