zoukankan      html  css  js  c++  java
  • 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]);
    }
  • 相关阅读:
    【linux]】lighttpd的日志格式
    【vi】awk为指定行的指定字段添加一个单词
    【Android】命令行操作-启动应用程序
    CCS设置第一个li的元素与其他li样式不同
    nginx+tomcat 下POST响应参数过大无法显示完整及文件下载服务遇到过大文件无法下载解决办法
    有重复行,查询时只保留最新一行的sql
    Android定时执行和停止某任务
    MySQL每天自动增加分区
    <html:option获取文本值
    easyui datagrid 增删改查示例
  • 原文地址:https://www.cnblogs.com/8023spz/p/9216425.html
Copyright © 2011-2022 走看看