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;
}
posted @ 2020-12-08 19:47  茄子Min  阅读(107)  评论(0编辑  收藏  举报