HDU-6252 - Subway Chasing(差分約束/不等式組)
阿新 • • 發佈:2020-12-08
HDU-6252 - Subway Chasing(差分約束/不等式組)
題目連結: HDU - 6252
題面:
題意:
雷格西桑和路易桑是好朋友,在同一家公司工作。他們總是一起乘地鐵去上班。他們的路線上有N個地鐵站,編號從1到N。1站是他們的家,N站是公司。
有一天,雷格西桑起床晚了。當他來到車站時,路易桑已經離開X分鐘了。雷格西桑非常著急,於是他開始和路易桑聊天,交流他們的位置。內容是雷格西桑在A站和B站之間,路易桑在C站和D站之間。
B等於A+ 1這意味著雷格西在A站和A+1之間, 或B等於A這意味著雷格西就是在車站A,反之亦然對於C和D同理.更重要的是,他們交流的時間不能早於雷格西桑的離開,也不能晚於路易桑的到來。
到達公司後,雷格西桑想知道相鄰地鐵站之間的間隔時間。請注意,每個站點的停止時間都被忽略。
思路:
設\(t_i=d_{i+1}-d_i\)
考慮到兩人的每一句聊天都對應著一個關於\(t_i\)的不等式組。
對應關係為:
-
若:\(a=b,c=d\)則:
- 若:\(a=c\),則表明兩人位置相同,又\(x>0\),故答案為”IMPOSSIBLE“,
- 否則:\(d_{i+1}=d_i+x\)
-
若:\(a = b , c < d\) ,則:\(d_{c}-d_a<x\)。
-
若:\(a < b , c = d\),則:\(d_d-d_a>x\),如果\(b!=c\),則\(d_c-d_b<x\)
-
若:\(a < b , c < d\)
否則:\(d_b-d_a>x\).
然後 用差分約束模型建圖,用spfa演算法跑最長路,若有正環則輸出無解。否則可得到最小解。
程式碼:
#include <bits/stdc++.h> using namespace std; typedef pair<int, int> pii; const int maxn = 3e3 + 10; vector<pii> e[maxn]; int cnt[maxn]; bool inque[maxn]; int dis[maxn]; const int inf = 2e9 + 5; #define fi first #define se second bool check(int n) { for (int i = 1; i <= n; ++i) { cnt[i] = 0; dis[i] = -1; inque[i] = 0; } queue<int> q; q.push(0); cnt[0] = 1; int temp; dis[0] = 0; while (!q.empty()) { temp = q.front(); q.pop(); inque[temp] = 0; for (auto x : e[temp]) { if (dis[x.fi] < dis[temp] + x.se) { dis[x.fi] = dis[temp] + x.se; if (!inque[x.fi]) { inque[x.fi] = 1; q.push(x.fi); cnt[x.fi]++; if (cnt[x.fi] > n) { return 0; } } } } } return 1; } #define mp make_pair int main() { int t; scanf("%d", &t); for (int icase = 1; icase <= t; ++icase) { int n, m, x; scanf("%d %d %d", &n, &m, &x); bool flag = 0; for (int i = 1; i <= m; ++i) { int a, b, c, d; scanf("%d %d %d %d", &a, &b, &c, &d); if (a > c) { flag = 1; } if (a == b && c == d) { if (a == c) { flag = 1; } e[b].push_back(mp(c, x)); e[c].push_back(mp(b, -x)); } else if (a == b && c < d) { e[c].push_back(mp(b, -(x - 1))); e[a].push_back(mp(d, x + 1)); } else if (a < b && c == d) { e[c].push_back(mp(b, -(x - 1))); e[a].push_back(mp(d, x + 1)); } else if (a < b && c < d && a != c) { e[a].push_back(mp(d, x + 1)); e[c].push_back(mp(b, -(x - 1))); } else { e[a].push_back(mp(b, x + 1)); } } int S = 0; for (int i = 1; i <= n; ++i) { e[S].push_back(mp(i, 0)); } for (int i = 1; i < n; ++i) { e[i].push_back(mp(i + 1, 1)); } printf("Case #%d: ", icase); if (!flag && check(n)) { for (int i = 2; i <= n; ++i) { printf("%d%c", dis[i] - dis[i - 1], i == n ? '\n' : ' '); } } else { printf("IMPOSSIBLE\n"); } for (int i = 0; i <= n; ++i) { e[i].clear(); } } return 0; }