1. 程式人生 > >Layout(POJ 3169)

Layout(POJ 3169)

lines 式表 ger strong limit int push desc main

  • 原題如下: Layout
    Time Limit: 1000MS Memory Limit: 65536K
    Total Submissions: 14484 Accepted: 6961

    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.
  • 題解:記第i號牛的位置d[i],首先,牛是按照編號順序排列的,所以有d[i]≤d[i+1]成立,其次,對於每對關系好的牛之間的最大距離限制,都有d[AL]+DL≥d[BL]成立,同樣對於每對關系不好的牛,都有d[AD]+DD≤d[BD]成立,因此,原問題就轉化為了在滿足這三類不等式的情況下,求解d[N]-d[1]的最大值的問題。這種線性規劃問題當然可以用單純形法來求,但這道題還比較特殊,這些不等式的兩邊都只有1個變量,這種特殊形式的不等式方程組又叫做差分約束系統,它可以用我們熟悉的圖論最短路算法來求。最短路問題可以用這種不等式的形式表示出來,記從起點s出發,到各個頂點v的最短距離為d(v),因此,對於每條權值為w的邊e=(v,u),都有d(v)+w≥d(u)成立,在滿足全部這些約束不等式中的d中,d(v)-d(s)的最大值就是從s到v的最短距離。對比差分約束與最短路問題,兩者具有完全一樣的形式,所以,可以把原來的問題的每一個約束不等式對應成圖中的一條邊來構圖,然後通過解決最短路問題來解決原問題。首先把頂點編號為1~N,d[i]≤d[i+1]變形為d[i+1]+0≥d[i],因此,從頂點i+1向頂點i連一條權值為0的邊,同樣d[AL]+DL≥d[BL]對應從頂點AL向頂點BL連一條權值為DL的邊,d[AD]+DD≤d[BD]對應從BD向頂點AD連一條權值為-DD的邊。所求的問題是d[N]-d[1]的最大值,對應為頂點1到頂點N的最短距離。
  • 代碼:
      1 #include <cstdio>
      2 #include <queue>
      3 #include <cctype>
      4 #define num s-‘0‘
      5 using namespace std;
      6 
      7 struct edge
      8 {
      9     int to;
     10     int cost;
     11 };
     12 
     13 const int INF=0x3f3f3f3f;
     14 const int MAX_V=1000;
     15 vector<edge> G[MAX_V];
     16 int V, ML, MD;
     17 int d[MAX_V];
     18 bool inque[MAX_V];
     19 int n[MAX_V];
     20 
     21 void read(int &x){
     22     char s;
     23     x=0;
     24     bool flag=0;
     25     while(!isdigit(s=getchar()))
     26         (s==-)&&(flag=true);
     27     for(x=num;isdigit(s=getchar());x=x*10+num);
     28     (flag)&&(x=-x);
     29 }
     30 
     31 void write(int x)
     32 {
     33     if(x<0)
     34     {
     35         putchar(-);
     36         x=-x;
     37     }
     38     if(x>9)
     39         write(x/10);
     40     putchar(x%10+0);
     41 }
     42 
     43 bool spfa();
     44 
     45 int main()
     46 {
     47     read(V); read(ML); read(MD);
     48     for (int i=0; i<ML; i++)
     49     {
     50         int A, B, C;
     51         read(A); read(B); read(C);
     52         edge e;
     53         e.to=B-1;e.cost=C;
     54         G[A-1].push_back(e);
     55     }
     56     for (int i=0; i<MD; i++)
     57     {
     58         int A, B, C;
     59         read(A); read(B); read(C);
     60         edge e;
     61         e.to=A-1;e.cost=-C;
     62         G[B-1].push_back(e);
     63     }
     64     for (int i=0; i<V-1; i++)
     65     {
     66         edge e;
     67         e.to=i;e.cost=0;
     68         G[i+1].push_back(e);
     69     }
     70     if (spfa())
     71     {
     72         if (d[V-1]==INF) write(-2);
     73         else write(d[V-1]);
     74     }
     75     else write(-1);
     76 }
     77 
     78 bool spfa()
     79 {
     80     fill(d, d+V, INF);
     81     fill(inque, inque+V, false);
     82     fill(n, n+V, 0);
     83     queue<int> que;
     84     d[0]=0;
     85     que.push(0);
     86     n[0]++;
     87     inque[0]=true;
     88     while (!que.empty())
     89     {
     90         int v=que.front();que.pop();
     91         inque[v]=false;
     92         for (int i=0; i<G[v].size(); i++)
     93         {
     94             if (d[G[v][i].to]>d[v]+G[v][i].cost)
     95             {
     96                 d[G[v][i].to]=d[v]+G[v][i].cost;
     97                 if (!inque[G[v][i].to]) 
     98                 {
     99                     que.push(G[v][i].to);
    100                     inque[G[v][i].to]=true;
    101                     if (++n[G[v][i].to]>V) return false;
    102                 }
    103             }
    104         }
    105     }
    106     return true;
    107 }

Layout(POJ 3169)