【POJ3169 】Layout (认真的做差分约束)

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

 
 
【题意】
  有 N 头奶牛正在排队,它们的编号为 1 到 N,约翰要给它们安排合适的排队位置,满足以下条
件:
  • 首先,所有奶牛要站在一条直线上。由于是排队,所以编号小的奶牛要靠前,不能让编号大的
奶牛插队。但同一个位置可以容纳多头奶牛,这是因为它们非常苗条的缘故
  • 奶牛喜欢和朋友靠得近点。朋友关系有 F 对,其中第 Ai 头奶牛和第 Bi 头奶牛是第 i 对朋友,
它们的距离不能超过 Ci
  • 奶牛还要和讨厌的同类保持距离。敌对关系有 E 对,其中第 Xi 头奶牛和第 Yi 头奶牛是第 i
敌人,它们的距离不能少于 Zi
  你能否帮助约翰找到一个合理的站位方法,满足所有奶牛的要求,而且让 1 号奶牛和 N 号奶牛间的
距离尽量大?

 
【分析】
  

  啊,当然很快看出是差分约束,然而,呵呵,我以前没弄清楚的后遗症,不知道怎样跑是距离最大的。。
  跑最短路求得就是最大的距离,跑最长路求的就是最小的距离。

 

代码如下:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 #define INF 0xfffffff
 9 #define Maxn 1010
10 #define Maxm 22010
11 
12 struct node
13 {
14     int x,y,c,next;
15 }t[Maxm];int len;
16 int first[Maxn];
17 
18 void ins(int x,int y,int c)
19 {
20     t[++len].x=x;t[len].y=y;t[len].c=c;
21     t[len].next=first[x];first[x]=len;
22 }
23 
24 int n;
25 int dis[Maxn],cnt[Maxn];
26 bool inq[Maxn];
27 
28 queue<int > q;
29 
30 int ffind()
31 {
32     memset(dis,63,sizeof(dis));
33     while(!q.empty()) q.pop();
34     dis[1]=0;q.push(1);
35     while(!q.empty())
36     {
37         int x=q.front();
38         cnt[x]++;
39         if(cnt[x]>n) return -1;
40         for(int i=first[x];i;i=t[i].next)
41         {
42             int y=t[i].y;
43             if(dis[y]>dis[x]+t[i].c)
44             {
45                 dis[y]=dis[x]+t[i].c;
46                 if(!inq[y])
47                 {
48                     inq[y]=1;
49                     q.push(y);
50                 }
51             }
52         }
53         inq[x]=0;q.pop();
54     }
55     if(dis[n]>=INF-11000) return -2;
56     return dis[n];
57 }
58 
59 int main()
60 {
61     int f,e;
62     scanf("%d%d%d",&n,&f,&e);
63     len=0;
64     memset(first,0,sizeof(first));
65     for(int i=1;i<=f;i++)
66     {
67         int x,y,c;
68         scanf("%d%d%d",&x,&y,&c);
69         ins(x,y,c);
70     }
71     for(int i=1;i<=e;i++)
72     {
73         int x,y,c;
74         scanf("%d%d%d",&x,&y,&c);
75         ins(y,x,-c);
76     }
77     for(int i=1;i<n;i++) ins(i+1,i,0);
78     int ans=ffind();
79     printf("%d\n",ans);
80     return 0; 
81 }
[POJ 3169]

 


 

认真的说一下差分约束的理解??

???

先说最短路吧,其实用最短路啊最长路啊都是可以的,但是我不会告诉你我就是在这里被坑到。

最短路的话,把所有约束都化成x-y<=k的形式,然后add(y,x,k)就可以了,这样跑最短路保证d[x]<=d[y]+k。

如果差分约束有解,那么一定有无穷解,因为我们可以把所有值同时加上k,所有约束同样成立。

所以问题往往是某两个数的差值的最大值 或者 最小值。

可以证明,跑最短路的话,d[x]一定是与d[st]的差值最大的

因为你的约束都是x-y<=k的形式,如果x与st联通,那么肯定是有几个表达式x-a1<=k1,a1-a2<=k2,...,ax-st<=kx,

把他们全部加起来有x-st<=xxx,我们用类似xxx的值建边的,所以求出来的一定是满足条件的最大的x。

在这个时候,如果你要求最小的x,那么,你就把x作为起点,st作为终点跑最短路,求出来的就是最小的差值的相反数

 

最长路刚好反过来啦,化成x-y>=k的形式,add(y,x,k),则保证d[x]>=d[y]+k。

这时d[x]一定是与d[st]的差值最小的

反转起点终点跑,就是得到最大的差值的相反数。

 

好了,还有无解的情况。

如果用最短路,图中有负环,则无解。 因为你负环,说明有一些约束相加得到:x-k<=x,并且k是负数,显然不成立,so,无解。

同理,如果用最长路,图中有正环,也无解。因为这说明有约束的和为x-k>=x,且k是整数。

 

好像目前就知道这么多啦~~

 

如果你要求每个点都是非负数的情况下,某个点的最小非负值怎么破?

add一个源点,它的值为0,与他的差值就是那个数的真正的值。

然后就有约束 d[1]-d[st]>=0 d[2]-d[st]>=0...d[n]-d[st]>=0

然后就求d[x]与d[st]的最小差值。

这种问法貌似很常见??

 

2016-10-21 18:04:51

posted @ 2016-10-21 18:00  konjak魔芋  阅读(879)  评论(0编辑  收藏  举报