【poj3169 Layout】【差分約束】【Bellman-Ford】
阿新 • • 發佈:2018-12-12
【連結】
【題意】
有N個點,其中有ml個限制條件:點a,點b,的最長距離為d,有md個限制條件,點a,點b,的最短距離為d;點按序號順序排,求第一個點到最後一個點的最長距離。
【思路】
記錄第i號牛的位置d[i],首先,牛是按標號排序的,有d[i]<=d[i+1].
對於關係好的牛之間的最大距離,有d[AL]+DL<=d[BL].同樣有:d[AD]+DD<=d[BD].
問題轉化為,在滿足三類不等式條件下的d[N]-d[1]的最大值
不等式特點:所有式子兩邊都只出現了一個變數。
最短路問題中:記從點s出發,到各個頂點v的最短路的距離為d[v].因此,對於每條權值為w的邊e=(v,u),都有d(v)+w>=d(u).
反之,對於每條滿足不等式的d中,d(v)-d(s)的最大值就是從s-v的最距離。
【程式碼】
#include<cstdio> #include<math.h> #include<string> #include<vector> #include<algorithm> #include<iostream> using namespace std; const int maxn = 1e5 + 6; const int inf = 0x3f3f3f3f; int d[maxn]; struct node1 { int a,b,c; }k1[maxn]; struct node2 { int a, b, c; }k2[maxn]; int main() { //freopen("binary.in", "r", stdin); //freopen("binary.out", "w", stdout); memset(d, inf, sizeof(d)); d[0] = 0; int n, ml, md; scanf("%d%d%d", &n, &ml, &md); //A B D:B-A>=D for (int i = 0; i < ml; i++) { int a, b, d; scanf("%d%d%d", &k1[i].a, &k1[i].b, &k1[i].c); } //A B D:B-A<=D for (int i = 0; i < md; i++) { int a, b, d; scanf("%d%d%d", &k2[i].a, &k2[i].b, &k2[i].c); } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if(d[j+1]<inf)d[j] = min(d[j], d[j + 1]); } for (int j = 0; j < ml; j++) { if(d[k1[j].a-1]<inf) d[k1[j].b - 1] = min(d[k1[j].b - 1], d[k1[j].a - 1] + k1[j].c); } for (int j = 0; j < md; j++) { d[k2[j].a - 1] = min(d[k2[j].a - 1], d[k2[j].b - 1] - k2[j].c); } } if (d[0] < 0)printf("-1\n"); else if (d[n - 1] == inf)printf("-2\n"); else printf("%d\n", d[n - 1]); }