P蒜头君当大厨(差分约束)

来源:互联网 发布:word for mac迅雷下载 编辑:程序博客网 时间:2024/04/16 14:28

问题描述

蒜头君苦练厨艺,终于成为了某高档酒店的大厨。 每天上班,蒜头君会被要求做 nnn
份菜。既然是高档酒店,那么客人们当然是很讲究的,尤其对于上菜的时间有很多要求。客人们的要求被分成下列四种: 菜品 a 的上菜时间必须比菜品
b的上菜时间早 d 分钟或者更早。 菜品 a的上菜时间必须比菜品 b的上菜时间迟 d分钟或者更迟。 菜品 a 的上菜时间在 d
分钟以后(包含 d 分钟)。 菜品 a 的上菜时间在 d 分钟之前(包含 d 分钟)。 蒜头君的上班时间记为 0
分钟。为了节约时间,在满足客人们要求的情况下,蒜头君希望最后上的一道菜的时间尽可能的早。(每道菜的上菜时间必须不早于蒜头君的上班时间)

输入格式

第一行输入一个整数 n,表示一共需要上 n 道菜。 第二行输入一个整数 m,表示客人们的要求数量。 接下里 m 行,每行先输入一个整数
op。 如果 op=1,表示描述里的第 1 种要求,后面跟着三个整数 a,b,d; 如果 op=2,表示描述里的第 2
种要求,后面跟着三个整数 a,b,d; 如果 op=3,表示描述里的第 3 种要求,后面跟着两个整数 a,d; 如果
op=4,表示描述里的第 4 种要求,后面跟着两个整数 a,d。 输出格式 能满足客人们的要求,输出最后一道菜的上菜时间;否则输出一行 I
can’t。

样例输入 1
3

5

2 3 2 10

2 2 1 2

2 3 2 5

1 2 3 7

3 3 9
样例输出 1
12
样例输入 2
3

4

3 1 3

2 3 1 9

2 1 3 -1

1 1 2 5
样例输出 2
I can’t

题解

裸的差分约束,注意下原点的连接方式!
初始时dis【0】=0 其他边为-1
再向每条边连一条长度为零的边

代码

#include<stdio.h>#include<algorithm>#include<cmath>#include<cstring>#include<iostream>#include<queue>#include<cstdio>using namespace std;#define maxn 40005int n,m;int dis[maxn];int End[maxn],Next[maxn],Len[maxn],Last[maxn];int cnt;void insert(int x,int y,int z){    Next[++cnt]=Last[x];    Last[x]=cnt;    End[cnt]=y;    Len[cnt]=z;}queue<int>q;bool mark[maxn];int ct[maxn];bool flag=false;void spfa(){    int i,j,k;    for(i=1;i<=n;i++)dis[i]=-1;    q.push(0);    mark[0]=true;    while(q.size())    {        int t=q.front();        ct[t]++;        if(ct[t]==n+1){            flag=true;            break;        }        q.pop();        mark[t]=false;        for(i=Last[t];i;i=Next[i])        {            int en=End[i];            if(dis[t]+Len[i]>dis[en]){                dis[en]=dis[t]+Len[i];                if(mark[en]==false){                    mark[en]=true;                    q.push(en);                }            }        }    }}int main(){//  freopen("chef.in","r",stdin);//  freopen("chef.out","w",stdout);    int i,j,k;    scanf("%d%d",&n,&m);    for(i=1;i<=n;i++)insert(0,i,0);    for(i=1;i<=m;i++)    {        int x,a,b,d;        scanf("%d",&x);        if(x==1){            scanf("%d%d%d",&a,&b,&d);            insert(a,b,d);        }        if(x==2){            scanf("%d%d%d",&a,&b,&d);            insert(b,a,d);        }        if(x==3){            scanf("%d%d",&a,&d);            insert(0,a,d);        }        if(x==4){            scanf("%d%d",&a,&d);            insert(a,0,-d);        }    }    spfa();    int ans=0;    if(flag==true){        cout<<"I can't";        return 0;    }    for(i=1;i<=n;i++)ans=max(ans,dis[i]);    cout<<ans;}
原创粉丝点击