17 哈尔滨CCPC final J - Subway Chasing 差分约束

题目:https://vjudge.net/problem/HDU-6252

Mr. Panda and God Sheep are roommates and working in the same company. They always take subway to work together. There are NN subway stations on their route, numbered from 1 to NN. Station 1 is their home and station NN is the company.
One day, Mr. Panda was getting up later. When he came to the station, God Sheep has departed XX minutes ago. Mr. Panda was very hurried, so he started to chat with God Sheep to communicate their positions. The content is when Mr. Panda is between station AA and BB, God Sheep is just between station CC and DD.
BB is equal to A+1A+1 which means Mr. Panda is between station AA and A+1A+1 exclusive, or BB is equal to AA which means Mr. Panda is exactly on station AA. Vice versa for CC and DD. What’s more, the communication can only be made no earlier than Mr. Panda departed and no later than God Sheep arrived.
After arriving at the company, Mr. Panda want to know how many minutes between each adjacent subway stations. Please note that the stop time at each station was ignored.

Input

The first line of the input gives the number of test cases, TT. TT test cases follow.
Each test case starts with a line consists of 3 integers NN, MM and XX, indicating the number of stations, the number of chat contents and the minute interval between Mr. Panda and God Sheep. Then MM lines follow, each consists of 4 integers AA, BB, CC, DD, indicating each chat content.
1≤T≤301≤T≤30
1≤N,M≤20001≤N,M≤2000
1≤X≤1091≤X≤109
1≤A,B,C,D≤N1≤A,B,C,D≤N
A≤B≤A+1A≤B≤A+1
C≤D≤C+1C≤D≤C+1

Output

For each test case, output one line containing “Case #x: y”, where xx is the test case number (starting from 1) and yy is the minutes between stations in format t1,t2,...,tN−1t1,t2,...,tN−1. titi represents the minutes between station ii and i+1i+1. If there are multiple solutions, output a solution that meets 0<ti≤2×1090<ti≤2×109. If there is no solution, output “IMPOSSIBLE” instead.

Sample Input

2
4 3 2
1 1 2 3
2 3 2 3
2 3 3 4
4 2 2
1 2 3 4
2 3 2 3

Sample Output

Case #1: 1 3 1
Case #2: IMPOSSIBLE

        
  

Hint

In the second test case, when God Sheep passed the third station, Mr. Panda hadn’t arrived the second station. 
They can not between the second station and the third station at the same time.

表示好久没写差分约束复习一下。

题意:

AS比BS晚出发x分钟。 每次AS和BS会报道两人的位置,

若A = B 表示AS在A

A != B 表示AS 在A和B之间。

同理BS也一样。

问你每个位置之间的距离需要的时间。

思路:

可以把它当成一条线来想。

首先每个位置之间至少要1分钟

所以 dis[i]-dis[i-1] >= 1;

然后若A!=B && B!= C && C!= D

就可以转换成 dis[B]-dis[C] >= 1-x;

后面其他情况也可以同理推出。

然后可以看出 所有距离最小的情况,也就是 A-B>=x -> A>=B+x -> A=B+x ,也就可以连边成B->A ==x 为了保证符合条件的最小值,所以求个最长路,若有环出现也就是不可成立。

ac代码:

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const ll mx = 2e3+100;
const ll mod = 1e9+7;
ll si;
ll head[mx];
struct edge {
    ll v, d, nex;
}E[10*mx];

ll dis[mx], vis[mx], ds[mx];

void add(ll u, ll v, ll d) {
    E[si].v = v, E[si].d = d, E[si].nex = head[u];
    head[u] = si++;
}

void init() {
    memset(head, -1, sizeof(head));
    memset(dis, -1, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    memset(ds, 0, sizeof(ds));
    si = 0;
}

bool spfa(ll u, ll n) {
    queue<ll>q;
    q.push(u);
    dis[u] = 0;
    while (!q.empty()) {
        u = q.front();
        q.pop();
        vis[u] = false;
        for (ll i = head[u]; ~i; i = E[i].nex) {
            ll v = E[i].v, d = E[i].d+dis[u];
            if(dis[v] == -1 || dis[v] < d) {
                dis[v] = d;
                ds[v]++;
                if (ds[v] > n+1)
                    return false;
                if (!vis[v]) {
                    q.push(v);
                    vis[v] = true;
                }
            }
        }
    }
    return true;
}

int main() {
    ll n, m, q, x, y, k;
    scanf("%lld", &q);
    for (ll i = 1; i <= q; ++i) {
        printf("Case #%lld: ", i);
        init();
        scanf("%lld%lld%lld", &n, &m, &k);
        for (ll i = 2; i <= n; ++i) add(i-1, i, 1);
        for (ll i = 0; i < m; ++i) {
            ll a, b, c, d;
            scanf("%lld%lld%lld%lld", &a, &b, &c, &d);
            if (a == b) {
                if (c == d) add(a, c, k), add(c, a, -k);
                else add(c, a, 1-k), add(a, d, k+1);
            }
            else {
                if (c == d) add(d, b, 1-k), add(a, d, k+1);
                else add(c, b, 1-k), add(a, d, k+1);
            }
        }
        if (spfa(1, n)) {
            for (ll i = 2; i <= n; ++i) {
                printf("%lld%c", dis[i]-dis[i-1], (i == n)?'\n':' ');
            }
        }
        else puts("IMPOSSIBLE");
    }
    return 0;
}
发布了74 篇原创文章 · 获赞 29 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/ClonH/article/details/103097313