1. 程式人生 > >hdu 6252 Subway Chasing(差分約束)

hdu 6252 Subway Chasing(差分約束)

Subway Chasing

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 900    Accepted Submission(s): 299Special Judge  

Problem Description

Mr. Panda and God Sheep are roommates and working in the same company. They always take subway to work together. There are N

subway stations on their route, numbered from 1 to N. Station 1 is their home and station N is the company. One day, Mr. Panda was getting up later. When he came to the station, God Sheep has departed X 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 A
and B, God Sheep is just between station C and D.B is equal to A+1 which means Mr. Panda is between station A and A+1 exclusive, or B is equal to A which means Mr. Panda is exactly on station A. Vice versa for C and D. 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, T. T test cases follow. Each test case starts with a line consists of 3 integers N, M and X, indicating the number of stations, the number of chat contents and the minute interval between Mr. Panda and God Sheep. Then M lines follow, each consists of 4 integers A, B, C, D, indicating each chat content. 1≤T≤30 1≤N,M≤2000 1≤X≤109 1≤A,B,C,DNABA+1CDC+1

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the minutes between stations in format t1,t2,...,tN−1. ti represents the minutes between station i and i+1. If there are multiple solutions, output a solution that meets 0<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.

Source

Recommend

liuyiding   |   We have carefully selected several similar problems for you:  6447 6446 6445 6444 6443 

題意:

就是給了兩個人的行走位置。b比a晚走x分鐘。然後兩個人在每一時刻彙報一下兩個人的位置。如果在確定點i,就彙報(i,i),如果在兩點中間,就彙報(i,i+1).。。。問能否存在一個解使得彙報的成立,並輸出i~i+1之間的距離。

思路:

差分約束:

分為幾種情況:

1.當a,b,c,d都不相同時:

d-a<x  && c-b>x

2.當a==b 時:

①當c==d時{

此時就是點到點的距離了,並且距離肯定是X。轉化為兩個不等關係:c-b>=x && c-b<=x

}

②當c!=d時,就是   d-a<x && d-c>x

3.當a!=b時:

①:當c==d時{

d-a<x  && d-b>x

}

②:當c!=d時就轉化為 四個都不相同的情況了。

還有一點不要忘記:就是兩點之間的距離一定要大於等於1    !!!!

根據上邊關係建邊即可。

建邊原則:

A-B<=C   就ADD(B,A,C)。。。

開始用的kuangbin大神的板子沒跑對。。。然後換了個板子就對了,還沒看出來kuangbin板子哪裡有問題。

程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>

using namespace std;

#define LL long long
const int INF=0x3F3F3F3F;
int cnt;
int n,m;
LL x;
int u,uu,v,vv,vis[2009],tot[2009];
int s[2009],nt[200009],e[200009];
LL val[200009],dis[2009];
void add(int u,int v,int x){
    nt[cnt]=s[u];
    s[u]=cnt;
    e[cnt]=v;
    val[cnt++]=x;
}
int spfa()
{
    memset(vis,0,sizeof vis);
    memset(dis,0,sizeof dis);
    memset(tot,0,sizeof tot);
    queue<int>q;
    q.push(1);
    vis[1]=1;
    tot[1]++;
    while(!q.empty())
    {
        int pre=q.front();
        q.pop();
        vis[pre]=0;
        for(int i=s[pre];~i;i=nt[i])
        {
            if(dis[e[i]]<dis[pre]+val[i])
            {
                dis[e[i]]=dis[pre]+val[i];
                if(!vis[e[i]])
                {
                    q.push(e[i]);
                    if((++tot[e[i]])>=n)
                        return 0;
                    vis[e[i]]=1;
                }
            }
        }
    }
    return 1;
}
int main()
{
    int t,a,b,c,d;
    LL x;
    int u,uu,v,vv;
    int cas=0;
    scanf("%d",&t);
    while(t--){
        cas++;
        cnt=1;//加邊計數,這個不要忘
        memset(s,-1,sizeof(s));
        scanf("%d%d%lld",&n,&m,&x);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&u,&uu,&v,&vv);
            if(u==uu)
            {
                if(v==vv)
                {
                   ///就是兩點不一樣,中間距離肯定是x
                    add(u,v,x);///v-u<=x
                    add(v,u,-x);///u-v<=-x, v-u>=x
                }
                else
                {
                    add(u,vv,x+1); /// vv-u < x
                    add(v,u,1-x);  ///u-v<=1-x,  v-u>x
                }
            }
            else
            {
                if(v==vv)
                {
                        add(u,v,x+1);  ///v-u < x
                        add(v,uu,1-x);  /// uu-v<=1-x      v-uu> x
                }
                else
                {
                        add(u,vv,x+1);///vv-u<=x+1   vv-u<x
                        add(v,uu,1-x);///uu-v>=1-x   v-uu<x
                }
            }
        }
       for(int i=2;i<=n;i++)
            add(i-1,i,1);
        int flag=spfa();
        printf("Case #%d:", cas);
        if(!flag)
            printf(" IMPOSSIBLE\n");
        else
        {
            for(int i=2;i<=n;i++)
                printf(" %lld",dis[i]-dis[i-1]);
            printf("\n");
        }
    }
    return 0;
}