bzoj1731: [Usaco2005 dec]Layout 排隊佈局(差分約束)
阿新 • • 發佈:2018-12-31
題目描述:當排隊等候餵食時,奶牛喜歡和它們的朋友站得靠近些。FJ有N(2<=N<=1000)頭奶牛,編號從1到N,沿一條直線站著等候餵食。奶牛排在隊伍中的順序和它們的編號是相同的。因為奶牛相當苗條,所以可能有兩頭或者更多奶牛站在同一位置上。即使說,如果我們想象奶牛是站在一條數軸上的話,允許有兩頭或更多奶牛擁有相同的橫座標。一些奶牛相互間存有好感,它們希望兩者之間的距離不超過一個給定的數L。另一方面,一些奶牛相互間非常反感,它們希望兩者間的距離不小於一個給定的數D。給出ML條關於兩頭奶牛間有好感的描述,再給出MD條關於兩頭奶牛間存有反感的描述。(1<=ML,MD<=10000,1<=L,D<=1000000)你的工作是:如果不存在滿足要求的方案,輸出-1;如果1號奶牛和N號奶牛間的距離可以任意大,輸出-2;否則,計算出在滿足所有要求的情況下,1號奶牛和N號奶牛間可能的最大距離。
輸入格式:第一行:三個整數n,Ml,Md,用空格分隔。
第2 ~ Ml+1行:每行三個整數a,b,c。表述a與b之間的距離應≤c。保證a < b。
第Ml+2 ~ ML+Md+1行:每行三個整數a,b,c。表述a與b之間的距離應≥D 。保證a < b。
輸出格式:一行,一個整數。如果沒有合法方案,輸出 -1. 如果有合法方案,但 1 號奶牛可以與 N 號奶牛相距無窮遠,輸出 -2. 否則,輸出 1 號奶牛與 N 號奶牛間的最大距離。
輸入樣例:
4 2 1
1 3 10
2 4 20
2 3 3
輸出樣例:
27
解析:一道差分約束的經典題。
由題意,可知要求\(d_b-d_a≤D,d_d-d_c≥D,d_{i+1}-d_{i}≥0\)
即\(d_b-d_a≤D,d_c-d_d≤D,d_{i}-d_{i+1}≤0\)
所以建邊後有spfa跑一次最短路即可。
若存在負環,則輸出-1。若無法連通,則輸出-2。
程式碼如下:
#include<cstdio> #include<queue> using namespace std; const int maxn = 1e5 + 5 ; int n, l, d, dis[maxn], vis[maxn], cnt[maxn]; int nxt[maxn], hed[maxn], to[maxn], val[maxn], tot; queue <int> que; int read(void) { char c; while (c = getchar(), c < '0' || c > '9'); int x = c - '0'; while (c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; return x; } void add(int x, int y, int v) { nxt[++ tot] = hed[x]; hed[x] = tot; to[tot] = y; val[tot] = v; } int spfa(void) { for (int i = 1; i <= n; ++ i) dis[i] = 2e9; vis[1] = 1; dis[1] = 0; cnt[1] = 1; que.push(1); while (!que.empty()) { int u = que.front(); vis[u] = 0; que.pop(); for (int i = hed[u]; i ; i = nxt[i]) { int v = to[i]; if (dis[v] > dis[u] + val[i]) { dis[v] = dis[u] + val[i]; if (!vis[v]) { if (++ cnt[v] > n) return -1; vis[v] = 1; que.push(v); } } } } if (dis[n] == 2e9) return -2; return dis[n]; } int main() { n = read(); l = read(); d = read(); for (int i = 2; i <= n; ++ i) add(i, i - 1, 0); for (int i = 1; i <= l; ++ i) { int x = read(), y = read(), v = read(); add(x, y, v); } for (int i = 1; i <= d; ++ i) { int x = read(), y = read(), v = read(); add(y, x, -v); } printf("%d", spfa()); return 0; }