HDU-6252 - Subway Chasing(差分约束/不等式组)
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\),如果\(a!=c\),则\(d_d-d_a>x,d_c-d_b<x\)
否则:\(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;
}
本博客为本人原创,如需转载,请必须声明博客的源地址。
本人博客地址为:www.cnblogs.com/qieqiemin/
希望所写的文章对您有帮助。