poj 3169 Layout

来源:互联网 发布:java培训班 编辑:程序博客网 时间:2024/04/28 00:18

[题目](http://poj.org/problem?id=3169
)

Layout
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 8946 Accepted: 4296
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.

有N头牛成一条直线从1到N编号,有些牛关系很好,不能离太远。有些牛关系不好不能离太近。对于输入第一行是N 、Ml、 Md,接下来Ml行每行三个数A,B,D,即A号与B号最多距离D个单位,接下来Md行,每行同样A,B,D,即A号与B号最少距离D个单位。

设d[i]为号牛的位置,d[1] = 0;题目中隐含的条件即为 d[i] <= d[i+1];
d[y] - d[x] <= w —> d[x] + w >= d[y];
d[y] - d[x] >= w —> d[y] + (-w) >= d[x];

#include "iostream"using namespace std;#define oo 1000000000 ///oo表示正无穷struct line{  ///建边    int u;        int v;    int w;    line(){        u = v = w = 0;    }}edge[20010];  int top = 0;void add(int u,int v,int w) {  ///将输入存入结构中    edge[top].u = u;    edge[top].v = v;    edge[top++].w = w;}int d[1010];  ///每个点的位置void f(int n){    for(int i = 1; i <= n; i++) d[i] = oo;  //将d初始化为oo    d[1] = 0;   1号牛的位置在0for(int i = 1; i <= n; i++) {        for(int j = 0; j < top; j++) { //对每一组进行处理            int u = edge[j].u;            int v = edge[j].v;            int w = edge[j].w;            if(d[u] < oo && d[u] + w <= d[v]) {   ///若d[u]< oo,则d[u]已经确定,d[u]+w <= d[v] 则d[v]未确定;                d[v] = d[u] + w;   //根据w确定d[v]                }        }    }    int flag = 1;    for(int j=0; j<top; j++){    ///检查负环        int u = edge[j].u;        int v = edge[j].v;        int w = edge[j].w;        if(d[u] < oo && d[u]+w<d[v]){ // 根据推导的公式检查是否存在不满足条件的元素,是则flag = 0            flag = 0;            break;        }    }        if(flag == 0){           cout << -1 << endl;        }        else if( d[n] == oo){  //如果d[n]没有更新则表示找不到1号到n号联通且确定的距离            cout << -2 << endl;        }        else cout << d[n] << endl;}int main(){    ios::sync_with_stdio(false);    int n,ml,md;    int a,b,d;    while(cin >> n >> ml >> md) {        for(int i = 0; i < ml; i++) {            cin >> a >> b >> d;            if(a > b) {  //保证a编号比b小                int t = a;                    a = b;                    b = t;            }            add(a,b,d);  //d[x] + w = d[y]        }        for(int i = 0; i < md; i++){            cin >> a >> b >> d;            if(a > b) {                int t = a;                    a = b;                    b = t;            }            add(b,a,-d); ///d[y] + (-w) = d[x]        }        f(n);        top = 0;///因为多组数据输入,下一组之前要初始化    }    return 0;}

这题数据有点水,例如
4 2 1
1 2 20
1 4 21
3 4 5 这组数据本应返回-1,但是AC代码下返回21

0 0
原创粉丝点击