题意非常长非常变态。一个人要到他男朋友家,他最初有R元以及T分钟的时间来赶到他男朋友家。有N个房子M条道路,每条道路有须要消耗的时间以及过路费,同一时候还要顺路做食盐生意,起初身上没有食盐,最多带B袋盐,每到达一个地方有三种操作能够选择:1.售出一袋食盐;2:购买一袋食盐;3:什么都不做。然后你以为结束了?不!它还存在平行宇宙,在一个城市能够选择穿越平行宇宙到达还有一个宇宙的这个城市,不同宇宙的食盐价格不同可是过路费和道路须要的时间是同样的,并且因为他是穿越党,他不能在别的宇宙回到自己家或者男朋友家,求最后是否能到达他男朋友家以及最多能有多少钱。

BFS+DP,由于时间是不可逆的,所以每次依照时间的先后来处理状态,因此须要用优先队列来处理。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <iomanip>
#include <set>
using namespace std;
typedef long long ll;
const int maxn=111;
const int maxm=222;
struct Edge//邻接表
{
int v;
int tim;//时间花费
int cost;//金钱花费
int next;
};
struct Node
{
int u,times,k,b;
bool operator < (const Node &a) const
{
return times>a.times;
}
};
Edge edges[maxm<<1];
int head[maxn];
int num=-1;;
int n,m,B,K,R,T;
int dp[maxn][210][7][7];
int inqueue[maxn][210][7][7];
int price[7][maxn];
void addEdge(int u,int v,int tim,int cost)
{
num++;
edges[num].v=v;
edges[num].tim=tim;
edges[num].cost=cost;
edges[num].next=head[u];
head[u]=num;
}
int bfs()
{
int flag=0;
memset(dp,0,sizeof(dp));
memset(inqueue,0,sizeof(inqueue));
dp[1][0][0][0]=R;//初始金钱
Node node,tmp;
priority_queue<Node>q;//优先队列,按时间处理
node.u=1;//起始状态
node.times=0;
node.k=0;
node.b=0;
inqueue[1][0][0][0]=1;
q.push(node);
while(!q.empty())
{
node=q.top();
q.pop();
if(node.times>T)//当队里的元素的时间都大于T就无需处理了
{
break;
}
int u=node.u;
if(u==n)
{
//cout<<node.times<<endl;
continue;
}
for(int i=head[u];i!=-1;i=edges[i].next)//走到下一个城市
{
int v=edges[i].v;
int cost,tim;
cost=dp[u][node.times][node.k][node.b]-edges[i].cost;//剩下的金钱
tim=node.times+edges[i].tim;//时间
if(tim>T||cost<0)//剪枝
{
continue;
}
if(v==n&&node.k!=0)//仅仅能在0宇宙到达第N个城市
{
continue;
}
if(v==n)//成功到达
{
flag=1;
}
tmp.u=v;
tmp.times=tim;
tmp.k=node.k;
if(u!=1&&u!=n)
{
if(node.b+1<=B&&cost-price[node.k][u]>dp[v][tim][node.k][node.b+1])//买一袋盐
{
dp[v][tim][node.k][node.b+1]=cost-price[node.k][u];
tmp.b=node.b+1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
if(node.b>0&&cost+price[node.k][u]>dp[v][tim][node.k][node.b-1])//卖一袋盐
{
dp[v][tim][node.k][node.b-1]=cost+price[node.k][u];
tmp.b=node.b-1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
}
if(cost>dp[v][tim][node.k][node.b])//不买盐
{
dp[v][tim][node.k][node.b]=cost;
tmp.b=node.b;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
}
if(u!=1&&u!=n)//穿越到下一个宇宙的这个城市
{
int cost=dp[u][node.times][node.k][node.b];//金钱不变
tmp.u=u;
tmp.k=(node.k+1)%K;
tmp.times=node.times+1;//看广告时间+1
if(tmp.times>T)
{
continue;
}
if(node.b+1<=B&&cost-price[node.k][u]>dp[u][tmp.times][tmp.k][node.b+1])//在这个宇宙的这个城市买盐
{
dp[u][tmp.times][tmp.k][node.b+1]=cost-price[node.k][u];
tmp.b=node.b+1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
if(node.b>0&&cost+price[node.k][u]>dp[u][tmp.times][tmp.k][node.b-1])//卖一袋盐
{
dp[u][tmp.times][tmp.k][node.b-1]=cost+price[node.k][u];
tmp.b=node.b-1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
tmp.b=node.b;
if(cost>dp[u][tmp.times][tmp.k][tmp.b])//不做操作
{
dp[u][tmp.times][tmp.k][tmp.b]=cost;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
}
}
if(!flag)
{
return -1;//不能到达
}
int ans=0;
for(int i=0;i<=T;i++)
{
for(int j=0;j<=B;j++)
{
ans=max(ans,dp[n][i][0][j]);//能够到达,在能够到的的情况中选取钱最多的
}
}
return ans;
}
int main()
{
int t;
int s=1;
int u,v,tim,cost;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d%d%d",&n,&m,&B,&K,&R,&T);//城市数目,道路数目,食盐上限,宇宙个数,初始金钱,时间上限
memset(head,-1,sizeof(head));
num=-1;
for(int i=0;i<K;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&price[i][j]);//食盐在每一个宇宙每一个城市的价格
}
}
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&u,&v,&tim,&cost);//每条路的起点,终点,时间,花费
addEdge(u,v,tim,cost);
}
int ans;
ans=bfs();
printf("Case #%d: ",s++);
if(ans!=-1)
{
printf("%d\n",ans);
}
else
{
printf("Forever Alone\n");
}
}
return 0;
}

HDU--4784 Dinner Coming Soon DP+BFS的更多相关文章

  1. hdu 4784 Dinner Coming Soon(spfa + 优先队列)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4784 思路:建图,对于同一个universe来说,就按题目给的条件相连,对于相邻的universe,连 ...

  2. HDU 3001 Travelling (状压DP + BFS)

    题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次.现在给出城市之间的来往路费,他可以选择任意一个点为起点. 问逛遍所有城市的最低路费是多少. 析:用三进制表示每个城市的访问 ...

  3. hdu 4784 Dinner Coming Soon

    spfa+优先队列.刚开始只用的spfa,结果tle到死.然后听队友说要用到优先队列,想了想,对时间分层的话的确每一个结点都只进队列一次即可,因为只有大时间才能更新出小时间,然后就wa成shi了.按队 ...

  4. hdu 3247 AC自动+状压dp+bfs处理

    Resource Archiver Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Ot ...

  5. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  6. hdu 5094 Maze 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...

  7. hdu 3681 Prison Break(状态压缩+bfs)

    Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...

  8. hdu 2829 Lawrence(斜率优化DP)

    题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...

  9. hdu 4568 Hunter 最短路+dp

    Hunter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. Word03-文档中的截图显示不全

    今天写文档时遇到个很蛋疼的问题,在doc文档中复制进去的截图总是显示不全,图片上半部分都被文字遮盖了,折腾半天,最后还是网上找到了答案. 解决方法如下: 将图片所在行的段落行距修改为其它值即可,原来为 ...

  2. python:字符串取值

    某个字符串为stmp="abcdef54321" 取前面5个stmp[:5] #abcde 取后面5个stmp[-5:] #54321 从前面开始取,不包括最后两个stmp[:-2 ...

  3. 为什么class中属性以空格分隔?

    1 div.contain .blue{color:blue;}/*后代选择器*/2 div.contain.blue{color:blue;} /*多类选择器*/ 以上两种规则分别应用的元素如下: ...

  4. FANTASY:In which way do you think the world will end?

    In which way do you think the world will end? The moment you are reading my essay, you are somehow c ...

  5. VC实用小知识总结 (一),转http://blog.csdn.net/myiszjf/article/details/10007431

    在上一篇中,我们以经介绍了程序的流程和框架,在本篇将详细讨论各个功能的实现主要包括 1.获取磁盘信息2.获取目录信息3.获取文件信息4.运行指定文件5.删除指定文件6.删除指定目录7.创建指定目录8. ...

  6. powerdesigner设置mysql唯一键,非主键

    员工表如下,先将id设置主键: 现在将"员工id"设置唯一约束: 1,切换到"Keys",发现已经存在一个Key1,这个是刚刚新增主键id.在Key1下发空行出 ...

  7. 转。webapp开发小tips

     备忘 - Q:  webapp点击一个按钮调用系统拨号: <a href="tel:12345654321">打电话给我</a> <a href=& ...

  8. Zepto源码笔记(二)

    uniq(array) 返回不存在重复值的数组 function classRE(name) 判断classCache中是否已存在name,若存在则取出classCache[name];否则存入该类名 ...

  9. 在Web开发方面Java跟PHp八大对比

    在Web开发方面Java跟PHp八大对比 <本文摘自百度经验,用来简单对比一下这两种语言> 一. 语言比较 PHP是解释执行的服务器脚本语言,首先php有简单容易上手的特点.语法和c语言比 ...

  10. 搭建Nuget

    1.  新建一个 ASP.NET 空Web应用程序 2. 在新建的项目中引用 安装 NuGet.Server 2.1 右键项目中的引用,出现一个“管理NuGet程序包(N)”,点击进入 2.2  在搜 ...