(BFS)HDU 4784 Dinner Coming Soon

Posted 惜取少年时

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(BFS)HDU 4784 Dinner Coming Soon相关的知识,希望对你有一定的参考价值。

  Coach Pang loves his boyfriend Uncle Yang very much. Today is Uncle Yang’s birthday, Coach Pang wants to have a romantic candlelit dinner at Uncle Yang’s house and he has to arrive there in T minutes. 
  There are N houses in their city numbered from 1 to N. Coach Pang lives in house 1 while Uncle Yang lives in house N. The houses are connected byM directed roads. It takes some time and usually a fee to pass one road. Coach Pang wants to reach Uncle Yang’s house before the dinner starts with as much money as possible. 
  But the matter is not so simple. Coach Pang decides to do some salt trade on the way to Uncle Yang’s house. The host of each house offers a price of a bag of salt, so Coach Pang can make a profit from the price differences. Each time when Coach Pang arrives at a house (except the house 1 and the house N). He can buy one bag of salt, sell one bag of salt or do nothing. Coach Pang can carry at most B bags of salt with him, and he carries no salt when he leaves his house. The trading is so efficient that the time cost of trading can be ignored. 
  However, the problem is more complicated than imagine. Coach Pang has a handheld device that can perform a journey around K parallel universes numbered from 0 to K-1. Coach Pang lives in the universe 0. When Coach Pang uses the device in universe i, he will be transported to the same place and the same time of universe (i+1) modK. The host of the house at the same place in different universe may offer a different price of salt. Luckily, the time cost and fee of the city roads are uniform among the K universes. The journey between universes costs no time but Coach Pang has to stand still watching the ads on the device for one minute every time before the device works. Remember, Coach Pang should never visit house 1 or house N in a universe other than universe 0, because the situation might become uncontrollable if he bumps into himself or his boyfriend in another universe. 
  The time is running out. Coach Pang asks you to tell him whether he can arrive at Uncle Yang’s house in time, and how much money Coach Pang can have at most when the dinner starts. Coach Pang has R yuan at the start, and will end his journey immediately once he arrives at Uncle Yang’s house. He must arrive at Uncle Yang’s house in T minutes, and he can’t have negative amount of money anywhere anytime. Please help him!

Input  The first line of the input is an integer C representing the number of test cases. 
  For each test case, the first line will contain 6 integers N, M, B, K, R, T, as described above. 
  (2 <= N <= 100, 0 <= M <= 200, 1 <= B <= 4, 2 <= K <= 5, 0 <= R <= 10 5, 0 <= T <= 200) 
  The following K lines contain N integers each, indicating the price p ij (0 <= i < K, 1 <= j <= N) for a bag of salt offered by the host of house j in the universe i. The price of house 1 and house N will be marked as -1.(1 <= p ij <= 100) 
  Then M lines follow, each contains 4 integers a, b, t and m, indicating that there is a road from house a to house b that costs t minutes of time and m yuan of money. (1 <= a,b <= N, a<> b, 1 <= t <=15, 0 <= m <= 100) 
Output  For each test case, output one line containing “Case #x: y”, where x is the case number (starting from 1) and y is the most money Coach Pang can have if he can have dinner with Uncle Yang on time. 
  Print "Forever Alone" otherwise.Sample Input

2
3 2 1 2 10 6
-1 1 -1
-1 5 -1
1 2 1 0
2 3 1 1
2 2 1 2 5 5
-1 -1
-1 -1
1 2 10 2
1 2 2 10

Sample Output

Case #1: 17
Case #2: Forever Alone

 

对于这道题,只是想记录一下自己的代码……

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <set>
  6 #include <map>
  7 #include <string>
  8 #include <cstring>
  9 #include <stack>
 10 #include <queue>
 11 #include <cmath>
 12 #include <ctime>
 13 #include <utility>
 14 using namespace std;
 15 #define REP(I,N) for (I=0;I<N;I++)
 16 #define rREP(I,N) for (I=N-1;I>=0;I--)
 17 #define rep(I,S,N) for (I=S;I<N;I++)
 18 #define rrep(I,S,N) for (I=N-1;I>=S;I--)
 19 #define FOR(I,S,N) for (I=S;I<=N;I++)
 20 #define rFOR(I,S,N) for (I=N;I>=S;I--)
 21 typedef unsigned long long ull;
 22 typedef long long ll;
 23 const int INF=0x3f3f3f3f;
 24 const ll INFF=0x3f3f3f3f3f3f3f3fll;
 25 const ll M=1e6+3;
 26 const ll maxn=1e5+7;
 27 const int MAX=5e5+5;
 28 const int MAX_N=MAX;
 29 const ll MOD=1e6+3;
 30 const double eps=0.00000001;
 31 ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
 32 template<typename T>inline T abs(T a) {return a>0?a:-a;}
 33 inline ll powMM(ll a,ll b){ll ret=1;while (b){if (b&1)ret=ret*a%M;b>>=1;a=a*a%M;}return ret;}
 34 int dp[101][202][10][10];
 35 bool vi[101][202][10][10];
 36 int head[205];//链表的起始点 储存从某个点出发的连向其他点的边的链表
 37 int edgenum;//边的个数 从0开始
 38 int prices[10][105];//盐的价格
 39 bool arrival;//能否在T时间内到达n
 40 struct edge
 41 {
 42     int target,t,money;
 43     int nxt;
 44 }edges[MAX];
 45 void addedge(int now,int to,int time_cost,int money_cost)
 46 {
 47     edgenum++;
 48     edges[edgenum].target=to;
 49     edges[edgenum].t=time_cost;
 50     edges[edgenum].money=money_cost;
 51     edges[edgenum].nxt=head[now];
 52     head[now]=edgenum;
 53 //    printf("now=%d edgenum=%d\n",now,edgenum);
 54 }
 55 struct node
 56 {
 57     int lo,t,k,pack;
 58     bool operator <(const node &a)const
 59     {
 60         return t>a.t;
 61     }
 62 };
 63 priority_queue<node> que;
 64 void init()//初始化函数
 65 {
 66     memset(head,0xff,sizeof(head));//将链表头初始化为-1
 67     memset(vi,false,sizeof(vi));
 68     memset(dp,0,sizeof(dp));
 69     edgenum=-1;
 70     arrival=false;
 71     while(!que.empty())//清空优先队列
 72         que.pop();
 73 }
 74 int n,m,b,k,r,T;
 75 int solve()
 76 {
 77     node tem;
 78     tem.lo=1;tem.t=0;tem.k=0;tem.pack=0;
 79     que.push(tem);
 80     vi[1][0][0][0]=true;
 81     dp[1][0][0][0]=r;
 82     while(!que.empty())
 83     {
 84         tem=que.top();
 85         que.pop();
 86         if(tem.t>T||tem.lo==n)continue;
 87 //        printf("%d! %d\n",tem.lo,head[tem.lo]);
 88         for(int i=head[tem.lo];i!=-1;i=edges[i].nxt)
 89         {
 90 //            printf("nxt %d!\n",edges[i].nxt);
 91             int new_time,new_money;
 92             new_time=tem.t+edges[i].t;
 93             new_money=dp[tem.lo][tem.t][tem.k][tem.pack]-edges[i].money;
 94             if(new_time>T||new_money<0)continue;
 95             if(edges[i].target==n&&tem.k!=0)continue;
 96             if(edges[i].target==n)arrival=true;
 97             if(tem.lo!=1&&tem.lo!=n)//是可以进行盐买卖的点
 98             {
 99                 //买一包盐
100                 if(tem.pack<b&&new_money-prices[tem.k][tem.lo]>dp[edges[i].target][new_time][tem.k][tem.pack+1])
101                 {
102                     dp[edges[i].target][new_time][tem.k][tem.pack+1]=new_money-prices[tem.k][tem.lo];
103                     if(!vi[edges[i].target][new_time][tem.k][tem.pack+1])
104                     {
105                         vi[edges[i].target][new_time][tem.k][tem.pack+1]=true;
106                         node nxt;
107                         nxt.k=tem.k;nxt.lo=edges[i].target;nxt.pack=tem.pack+1;nxt.t=new_time;
108                         que.push(nxt);
109                     }
110                 }
111                 //卖一包盐
112                 if(tem.pack&&new_money+prices[tem.k][tem.lo]>dp[edges[i].target][new_time][tem.k][tem.pack-1])
113                 {
114                     dp[edges[i].target][new_time][tem.k][tem.pack-1]=new_money+prices[tem.k][tem.lo];
115                     if(!vi[edges[i].target][new_time][tem.k][tem.pack-1])
116                     {
117                         vi[edges[i].target][new_time][tem.k][tem.pack-1]=true;
118                         node nxt;
119                         nxt.k=tem.k;nxt.lo=edges[i].target;nxt.pack=tem.pack-1;nxt.t=new_time;
120                         que.push(nxt);
121                     }
122                 }
123             }
124             //不买不卖 与无法买卖的情况相同
125             if(new_money>dp[edges[i].target][new_time][tem.k][tem.pack])
126             {
127                 dp[edges[i].target][new_time][tem.k][tem.pack]=new_money;
128                 if(!vi[edges[i].target][new_time][tem.k][tem.pack])
129                 {
130                     vi[edges[i].target][new_time][tem.k][tem.pack]=true;
131                     node nxt;
132                     nxt.k=tem.k;nxt.lo=edges[i].target;nxt.pack=tem.pack;nxt.t=new_time;
133                     que.push(nxt);
134                 }
135             }
136         }
137         //再看看是不是要穿越……
138         if(tem.lo!=1&&tem.lo!=n)
139         {
140             int new_time=tem.t+1,new_k=(tem.k+1)%k;
141             int new_money=dp[tem.lo][tem.t][tem.k][tem.pack];
142             if(new_time>T)
143                 continue;
144             //买一包盐
145             if(tem.pack<b&&new_money-prices[tem.k][tem.lo]>dp[tem.lo][new_time][new_k][tem.pack+1])
146             {
147                 dp[tem.lo][new_time][new_k][tem.pack+1]=new_money-prices[tem.k][tem.lo];
148                 if(!vi[tem.lo][new_time][new_k][tem.pack+1])
149                 {
150                     vi[tem.lo][new_time][new_k][tem.pack+1]=true;
151                     node nxt;
152                     nxt.k=new_k;nxt.lo=tem.lo;nxt.pack=tem.pack+1;nxt.t=new_time;
153                     que.push(nxt);
154                 }
155             }
156             //卖一包盐
157             if(tem.pack&&new_money+prices[tem.k][tem.lo]>dp[tem.lo][new_time][new_k][tem.pack-1])
158             {
159                 dp[tem.lo][new_time][new_k][tem.pack-1]=new_money+prices[tem.k][tem.lo];
160                 if(!vi[tem.lo][new_time][new_k][tem.pack-1])
161                 {
162                     vi[tem.lo][new_time][new_k][tem.pack-1]=true;
163                     node nxt;
164                     nxt.k=new_k;nxt.lo=tem.lo;nxt.pack=tem.pack-1;nxt.t=new_time;
165                     que.push(nxt);
166                 }
167             }
168             //不买不卖
169             if(new_money>dp[tem.lo][new_time][new_k][tem.pack])
170             {
171                 dp[tem.lo][new_time][new_k][tem.pack]=new_money;
172                 if(!vi[tem.lo][new_time][new_k][tem.pack])
173                 {
174                     vi[tem.lo][new_time][new_k][tem.pack]=true;
175                     node nxt;
176                     nxt.k=new_k;nxt.lo=tem.lo;nxt.pack=tem.pack;nxt.t=new_time;
177                     que.push(nxt);
178                 }
179             }
180         }
181     }
182     if(!arrival)
183         return -1;
184     else
185     {
186         int an=0;
187         for(int i=0;i<=T;i++)
188             for(int j=0;j<=b;j++)
189                 an=max(an,dp[n][i][0][j]);
190         return an;
191     }
192 }
193 int main()
194 {
195     int c;
196     scanf("%d",&c);
197     for(int Case=1;Case<=c;Case++)
198     {
199         init();
200         scanf("%d%d%d%d%d%d",&n,&m,&b,&k,&r,&T);
201         for(int i=0;i<k;i++)
202             for(int j=1;j<=n;j++)
203                 scanf("%d",&prices[i][j]);//读入价格
204         for(int i=1;i<=m;i++)
205         {
206             int a,b,t,m;
207             scanf("%d%d%d%d",&a,&b,&t,&m);
208             addedge(a,b,t,m);
209         }
210         int an=solve();
211         if(an==-1)
212             printf("Case #%d: Forever Alone\n",Case);
213         else
214             printf("Case #%d: %d\n",Case,an);
215     }
216     return 0;
217 }

 

以上是关于(BFS)HDU 4784 Dinner Coming Soon的主要内容,如果未能解决你的问题,请参考以下文章

hdu2102 BFS

HDU 1240 Asteroids!(BFS)

hdu1254 推箱子 搜索水题(bfs+bfs)

HDU 1242 Rescue(BFS)

hdu-1181(bfs)

HDU 1372 Knight Moves(bfs)