HDU 4784 Dinner Coming Soon(BFS+优先队列+状态转移)

来源:互联网 发布:工业怪兽 知乎 编辑:程序博客网 时间:2024/04/30 12:31

分析:把时间作为优先队列的条件、然后bfs、

d[i][j][k][p]表示第i个城市、第j时刻、在第K维空间、有W包盐的最大价值

#include<stdio.h>#include<string.h>#include<queue>#include<algorithm>using namespace std;#define INF 0x7ffffffconst int N=105;const int M=205;int n,m,b,k,r,t;//第i个城市、第j分钟、第K维空间、有P包盐的最大价值int d[N][205][6][6];bool vis[N][205][6][6];int num[6][105];int cnt;struct edges{    int to,next,val,time;}edge[M];struct node{    int u,time,k,b;    friend bool operator <(node a,node b)    {        return a.time>b.time;    }};int head[N];void init(){    cnt=0;    memset(head,-1,sizeof(head));}int bfs(){    priority_queue<node>q;    memset(vis,false,sizeof(vis));    memset(d,0xff,sizeof(d));    node now,tmp;    now.b=0;    now.u=1;    now.k=0;    now.time=0;    d[1][0][0][0]=r;    q.push(now);    vis[1][0][0][0]=true;    bool flag=false;    while(!q.empty())    {        now=q.top();        q.pop();        if(now.time>t)break;        if(now.u==n)continue;        //到下一个城市        for(int i=head[now.u];i!=-1;i=edge[i].next)        {            int w=edge[i].to;            int f_cost=d[now.u][now.time][now.k][now.b]-edge[i].val;            int f_time=now.time+edge[i].time;            if(f_time>t||f_cost<0)continue;            if(w==n&&now.k!=0)continue;            if(w==n)flag=true;            tmp.u=w;            tmp.k=now.k;            tmp.time=f_time;            if(now.u!=1&&now.u!=n)            {                //买盐             如果在当前城市买了一袋盐且比以前的价值大                if(now.b+1<=b&&f_cost-num[now.k][now.u]>d[w][f_time][now.k][now.b+1])                {                    d[w][f_time][now.k][now.b+1]=f_cost-num[now.k][now.u];                    tmp.b=now.b+1;                    if(!vis[tmp.u][tmp.time][tmp.k][tmp.b])                    {                        q.push(tmp);                        vis[tmp.u][tmp.time][tmp.k][tmp.b]=true;                    }                }                //卖盐                if(now.b>0&&f_cost+num[now.k][now.u]>d[w][f_time][now.k][now.b-1])                {                    d[w][f_time][now.k][now.b-1]=f_cost+num[now.k][now.u];                    tmp.b=now.b-1;                    if(!vis[tmp.u][tmp.time][tmp.k][tmp.b])                    {                        q.push(tmp);                        vis[tmp.u][tmp.time][tmp.k][tmp.b]=true;                    }                }            }            //不交易            if(f_cost>d[w][f_time][now.k][now.b])            {                d[w][f_time][now.k][now.b]=f_cost;                tmp.b=now.b;                if(!vis[tmp.u][tmp.time][tmp.k][tmp.b])                {                    q.push(tmp);                    vis[tmp.u][tmp.time][tmp.k][tmp.b]=true;                }            }        }        //穿越        if(now.u!=1&&now.u!=n)        {            int f_cost=d[now.u][now.time][now.k][now.b];            tmp.u=now.u;            tmp.k=(now.k+1)%k;            tmp.time=now.time+1;            if(tmp.time>t)continue;            //买盐            if(now.b+1<=b&&f_cost-num[now.k][now.u]>d[now.u][tmp.time][tmp.k][now.b+1])            {                d[now.u][tmp.time][tmp.k][now.b+1]=f_cost-num[now.k][now.u];                tmp.b=now.b+1;                if(!vis[tmp.u][tmp.time][tmp.k][tmp.b])                {                    q.push(tmp);                    vis[tmp.u][tmp.time][tmp.k][tmp.b]=true;                }            }            //卖盐            if(now.b>0&&f_cost+num[now.k][now.u]>d[now.u][tmp.time][tmp.k][now.b-1])            {                d[now.u][tmp.time][tmp.k][now.b-1]=f_cost+num[now.k][now.u];                tmp.b=now.b-1;                if(!vis[tmp.u][tmp.time][tmp.k][tmp.b])                {                    q.push(tmp);                    vis[tmp.u][tmp.time][tmp.k][tmp.b]=true;                }            }            tmp.b=now.b;            //不交易            if(f_cost>d[now.u][tmp.time][tmp.k][tmp.b])            {                d[now.u][tmp.time][tmp.k][tmp.b]=f_cost;                if(!vis[tmp.u][tmp.time][tmp.k][tmp.b])                {                    q.push(tmp);                    vis[tmp.u][tmp.time][tmp.k][tmp.b]=true;                }            }        }    }    if(!flag)return -1;    int ans=0;    for(int i=0;i<=t;i++)    {        for(int j=0;j<=b;j++)        {            ans=max(ans,d[n][i][0][j]);        }    }    return ans;}void add(int x,int y,int val,int time){    edge[cnt].to=y;    edge[cnt].val=val;    edge[cnt].time=time;    edge[cnt].next=head[x];    head[x]=cnt++;}int main(){    int T;    int cas=1;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d%d%d%d",&n,&m,&b,&k,&r,&t);        init();        for(int i=0;i<k;i++)        {            for(int j=1;j<=n;j++)            {                scanf("%d",&num[i][j]);            }        }        for(int i=1;i<=m;i++)        {            int x,y,time,val;            scanf("%d%d%d%d",&x,&y,&time,&val);            add(x,y,val,time);        }        int ans=bfs();        printf("Case #%d: ",cas++);        if(ans!=-1)        {            printf("%d\n",ans);        }        else        {            printf("Forever Alone\n");        }    }    return 0;}


0 0
原创粉丝点击