题意非常长非常变态。一个人要到他男朋友家,他最初有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. Unity用户自定义圆角头像

    前天朋友遇到一个这样的需求,而且比较棘手让我帮忙解决.需求就是棋牌类的游戏,玩家的个人资料中包括自己的头像而且可以浏览相册中的图片或者使用相机拍照设置.关于这个问题我也查阅一些资料,由于涉及安卓部分知 ...

  2. 减少iOS应用程序安装包大小

    安装包优化大小方法: <资源优化> 1.去除无用资源 通过几次项目的升级后,项目中会出现一些没有用到的图片.这些图片在我们导入到项目中后,之后项目升级过程后并没有再次用到. 那这些图片我们 ...

  3. JS笔记-常见函数与问题

    1.请给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组. Array.prototype.distinct = functi ...

  4. spring项目中监听器作用-ContextLoaderListener(项目启动时,加载一些东西到缓存中)

    作用:在启动Web容器时,自动装配Spring applicationContext.xml的配置信息. 因为它实现了ServletContextListener这个接口,在web.xml配置这个监听 ...

  5. DropDownList获取的SelectIndex一直为0

    1.想要DropDownList自动提交必须设置AutoPostBack="true"属性,下面是代码: <asp:DropDownList ID=" AutoPo ...

  6. 【warning】clang the linker unused

    这个问题是 我在写第一个 mac os 下的helloworld遇到的 就像是 大家写第一个java中的 helloworld 肯定也是要在命令窗口下进行操作 一样 为了让一些和我一样的刚入门的孩子学 ...

  7. localhost 与 127.0.0.1 的区别

    localhost与127.0.0.1的区别是什么?相信有人会说是本地ip,曾有人说,用127.0.0.1比localhost好,可以减少一次解析.看来这个入门问题还有人不清楚,其实这两者是有区别的. ...

  8. 转载:JAVA中使用JSON进行数据传递

    转载网址:http://www.cnblogs.com/undead/archive/2012/07/18/2594900.html 最近在做一个基于JAVA Servlet的WEB应用以及对应的An ...

  9. css中“zoom:1”是什么意思

    继承性: 无 兼容性: IE 基本语法 zoom : normal | number 语法取值 normal : 默认值.使用对象的实际尺寸 number : 百分数 | 无符号浮点实数.浮点实数 ...

  10. 一步步教你如何源码编译Recovery

    *1 准备Ubuntu作为您的操作系统,笔者的版本是12.04_amd64. *2 准备 Android 源码的编译环境,主要是安装一些编译用到的lib库,以及同步源码的一些工具 ,如GIT,CURL ...