hdu4784 SPFA

来源:互联网 发布:淘宝 怎么红包 套现 编辑:程序博客网 时间:2024/05/29 11:57
题意:给你一个图要你在规定时间内从第一个点到n个点的赚的最多的钱。
一开始你有R元钱,你可以背的动B包盐,一共有K个平行空间,给你T的时间。
n个点m条边。每个点除了1和n点不能买盐卖盐,其余点都可以买盐卖盐,什么都不干。一开始在第0个平行空间里
每一步只能做一件事,就是到与这个点相连的点去买盐卖盐或者什么都不干,还可以移动到第(i+1)%k(花费1个单位的时间)
个平行空间里的相对位置去买盐,卖盐,
什么都不干,平行空间里的盐价是不一样的,但边的花费是一样的。到了n点就必须停止,也必须在第0个平行空间里。
。移动到其他平行空间也不能在1号点和第n号点,因为每个点的盐价格都不一样,这样可以赚取差价了。
然后每跳边有钱花费,和时间花费。
要你求从在规定时间内从1到n能够赚的最多的钱。


思路:四维spfa,有点像最短路。四维状态状态表示 在第n个点用了t时间到了第k个平行空间手上还有b袋盐的最多钱。
然后就是跑spfa,每一个点可以扩展6中状态,一种是去下一个点,买盐,卖盐,什么都不干,还要就是去下一个

平行空间里买,卖,啥都不干。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<queue>#include<vector>using namespace std;struct edge{    int from,to,ti,w;};struct node{ int x,t,k,b; friend bool operator < (node n1,node n2)    {        return n1.t>n2.t; //<为从大到小,>大于从小到大;    }};int dp[210][210][10][10];bool vis[210][210][10][10];int price[10][210];int n,m,B,K,R,T;vector<int>G[210];vector<edge>edges;void addedge(int x,int y,int t,int w){    edge v={x,y,t,w};    edges.push_back(v);    G[x].push_back(edges.size()-1);}int bfs(){    memset(vis,0,sizeof(vis));    memset(dp,-1,sizeof(dp));    dp[1][0][0][0]=R;    vis[1][0][0][0]=1;    int flag=1;    node a={1,0,0,0};   priority_queue<node>q;    q.push(a);    while(!q.empty())    {        a=q.top();        q.pop();        vis[a.x][a.t][a.k][a.b]=0;         if(a.t>T)  break;        if(a.x==n) continue;        for(int i=0;i<G[a.x].size();i++)        {            edge v=edges[G[a.x][i]];            if(v.to==n&&a.k!=0) continue;            int cost=dp[a.x][a.t][a.k][a.b]-v.w;            int time=a.t+v.ti;            if(cost<0||time>T) continue;            if(v.to==n) flag=0;            node bb={v.to,time,a.k};          if(v.to!=1&&v.to!=n)           {                      if(a.b+1<=B&&cost-price[a.k][v.to]>dp[v.to][time][a.k][a.b+1])            {                dp[v.to][time][a.k][a.b+1]=cost-price[a.k][v.to];                if(!vis[v.to][time][a.k][a.b+1])                {                     bb.b=a.b+1;                    q.push(bb);                    vis[v.to][time][a.k][a.b+1]=1;                }            }            if(a.b>0&&cost+price[a.k][v.to]>dp[v.to][time][a.k][a.b-1])            {               dp[v.to][time][a.k][a.b-1]=cost+price[a.k][v.to];               if(!vis[v.to][time][a.k][a.b-1])               {                   bb.b=a.b-1;                   q.push(bb);                   vis[v.to][time][a.k][a.b-1]=1;               }                        }          }          if(cost>dp[v.to][time][a.k][a.b])          {            dp[v.to][time][a.k][a.b]=cost;            if(!vis[v.to][time][a.k][a.b])            {   bb.b=a.b;                q.push(bb);                vis[v.to][time][a.k][a.b]=1;                      }                }       }        if(a.x!=1&&a.x!=n)        {            int cost=dp[a.x][a.t][a.k][a.b];            int time=a.t+1;            if(time>T) continue;            int k=(a.k+1)%K;            if(a.b+1<=B&&cost-price[k][a.x]>dp[a.x][time][k][a.b+1])            {               dp[a.x][time][k][a.b+1]=cost-price[k][a.x];               if(!vis[a.x][time][k][a.b+1])               {                   node bb={a.x,time,k,a.b+1};                   q.push(bb);                   vis[a.x][time][k][a.b+1]=1;               }                      }            if(a.b>0&&cost+price[k][a.x]>dp[a.x][time][k][a.b-1])            {                dp[a.x][time][k][a.b-1]=cost+price[k][a.x];                if(!vis[a.x][time][k][a.b-1])                {                    node bb={a.x,time,k,a.b-1};                    q.push(bb);                    vis[a.x][time][k][a.b-1]=1;                }                          }            if(cost>dp[a.x][time][k][a.b])            {                dp[a.x][time][k][a.b]=cost;                if(!vis[a.x][time][k][a.b])                {                    node bb={a.x,time,k,a.b};                    q.push(bb);                    vis[a.x][time][k][a.b]=1;                }                   }        }    }    if(flag) return -1;    int ans=0;    for(int i=0;i<=B;i++)    {        for(int j=0;j<=T;j++)        {            if(dp[n][j][0][i]>ans) ans=dp[n][j][0][i];        }    }    return ans;}int main(){    int t;    scanf("%d",&t);    int cas=1;    while(t--)    {        scanf("%d %d %d %d %d %d",&n,&m,&B,&K,&R,&T);        for(int i=1;i<=n;i++)        {            G[i].clear();        }        edges.clear();        for(int i=0;i<K;i++)        {            for(int j=1;j<=n;j++)            {                scanf("%d",&price[i][j]);            }        }        for(int i=1;i<=m;i++)        {            int x,y,t,w;            scanf("%d %d %d %d",&x,&y,&t,&w);            addedge(x,y,t,w);        }        int ans=bfs();        printf("Case #%d: ",cas++);        if(ans==-1) printf("Forever Alone\n");        else printf("%d\n",ans);    }}


原创粉丝点击