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): 299
Special 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,DN
ABA+1
CDC+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

2017中国大学生程序设计竞赛-总决赛-重现赛(感谢哈工大)

 

 

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值