ZOJ1232 Adventure of Super Mario spfa上的dp
很早之前听说有一种dp是在图上的dp,然后是在跑SPFA的时候进行dp,所以特地找了一题关于在SPFA的时候dp的。
题意:1~a是村庄 a+1~a+b是城堡,存在m条无向边。求由a+b->1的最短路,但是你有很多飞鞋,每双飞鞋可以跑一个固定的距离l,但是跑的时候要是碰到了城堡就要停下来,而且也不能停在路中间。
思路和代码参考了下面的这个网址:http://blog.csdn.net/acm_cxlove/article/details/8679230
思路:正常来说我们就跑SPFA就可以了,每次从队列里取点更新,但因为有了跑鞋,所以每次取点的时候还有多一种转移途径,因此我们就需要知道每次用了跑鞋之后从当前的点能够到达哪些点,这个时候我们就需要两点之间的距离,因为两点之间不能经过城堡,所以在跑SPFA的时候我们对于那些城堡的点我们就不再压入的跑SPFA.然后当dis[u][v]<=l的时候我们就可以转移了。
#pragma warning(disable:4996)
#include<cstring>
#include<cstdio>
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define maxn 120
#define maxm 120*120
#define inf 0x3f3f3f3f
using namespace std; int a, b, m, l, k; struct Edge
{
int u, v, w;
Edge(){}
Edge(int ui, int vi, int wi) :u(ui), v(vi), w(wi){}
}e[maxm];
int ecnt; int dis[maxn][maxn];
int vis[maxn];
int first[maxn];
int nxt[maxm]; void add(int u, int v, int w)
{
e[ecnt].u = u; e[ecnt].v = v; e[ecnt].w = w;
nxt[ecnt] = first[u];
first[u] = ecnt++;
} void spfa()
{
memset(dis, 0x3f, sizeof(dis));
queue<int> que;
for (int loc = 1; loc <= a + b; loc++){
while (!que.empty()) que.pop();
memset(vis, 0, sizeof(vis));
que.push(loc); vis[loc] = 1;
dis[loc][loc] = 0;
while (!que.empty()){
int u = que.front(); que.pop(); vis[u] = 0;
for (int i = first[u]; i != -1; i = nxt[i]){
int v = e[i].v, w = e[i].w;
if (dis[loc][v] > dis[loc][u] + w){
dis[loc][v] = dis[loc][u] + w;
if (v <= a&&!vis[v]){
que.push(v); vis[v] = 1;
}
}
}
}
}
} int dp[maxn][15]; int main()
{
int T; cin >> T;
while (T--)
{
scanf("%d%d%d%d%d", &a, &b, &m, &l, &k);
memset(first, -1, sizeof(first)); ecnt = 0;
int ui, vi, wi;
for (int i = 0; i < m; i++){
scanf("%d%d%d", &ui, &vi, &wi);
add(ui, vi, wi);
add(vi, ui, wi);
}
spfa();
memset(dp, 0x3f, sizeof(dp));
memset(vis, 0, sizeof(vis));
queue<int> que;
que.push(a + b);
dp[a + b][k] = 0;
vis[a + b] = 1;
while (!que.empty()){
int u = que.front(); que.pop(); vis[u] = 0;
for (int sh = 0; sh <= k; sh++){
for (int i = first[u]; i != -1; i = nxt[i]){
int v = e[i].v, w = e[i].w;
if (dp[v][sh] > dp[u][sh] + w){
dp[v][sh] = dp[u][sh] + w;
if (!vis[v]){
que.push(v); vis[v] = 1;
}
}
}
if (!sh) continue;
for (int v = 1; v <= a + b; v++){
if (u != v&&dis[u][v] <= l){
if (dp[v][sh - 1] > dp[u][sh]){
dp[v][sh - 1] = dp[u][sh];
if (!vis[v]){
que.push(v); vis[v] = 1;
}
}
}
}
}
}
int ans = inf;
for (int i = 0; i <= k; i++){
ans = min(ans, dp[1][i]);
}
printf("%d\n", ans);
}
return 0;
}
---恢复内容结束---
ZOJ1232 Adventure of Super Mario spfa上的dp的更多相关文章
- ZOJ1232 Adventure of Super Mario(DP+SPFA)
dp[u][t]表示从起点出发,到达i点且用了t次magic boot时的最短时间, 方程如下: dp[v][t]=min(dp[v][t],dp[u][t]+dis[u][v]); dp[v][t] ...
- UVA10269 Adventure of Super Mario(Floyd+DP)
UVA10269 Adventure of Super Mario(Floyd+DP) After rescuing the beautiful princess, Super Mario needs ...
- [题解]UVA10269 Adventure of Super Mario
链接:http://vjudge.net/problem/viewProblem.action?id=24902 描述:由城镇.村子和双向边组成的图,从A+B走到1,要求最短路.有K次瞬移的机会,距离 ...
- UVA 10269 Adventure of Super Mario
看了这里 http://blog.csdn.net/acm_cxlove/article/details/8679230的分析之后自己又按照自己的模板写了一遍,算是对spfa又加深了一步认识(以前真是 ...
- UVa 10269 Adventure of Super Mario (Floyd + DP + BFS)
题意:有A个村庄,B个城市,m条边,从起点到终点,找一条最短路径.但是,有一种工具可以使人不费力的移动L个长度,但始末点必须是城市或村庄.这种工具有k个,每个只能使用一次,并且在城市内部不可使用,但在 ...
- UVA-10269 Adventure of Super Mario (dijkstra)
题目大意:有A个村庄,B个城市,m条边,从起点到终点,找一条最短路径.但是,有一种工具可以使人不费力的移动L个长度,但始末点必须是城市或村庄.这种工具有k个,每个只能使用一次,并且在城市内部不可使用, ...
- ZOJ 1232 Adventure of Super Mario (Floyd + DP)
题意:有a个村庄,编号为1到a,有b个城堡,编号为a+1到a+b.现在超级玛丽在a+b处,他的家在1处.每条路是双向的,两端地点的编号以及路的长度都已给出.路的长度和通过所需时间相等.他有一双鞋子,可 ...
- ZOJ2923 Calculate Roads(SPFA上的dp)
算是学了图dp后的第一次应用吧.题目其实真的是非常不严谨,什么都没说,基本靠猜,而且严格来说数据应该会有爆int的,不过不管那么多啦,思路对了就好- -0 #include<iostream&g ...
- zoj1232Adventure of Super Mario(图上dp)
题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...
随机推荐
- redis setnx 分布式锁
private final String RedisLockKey = "RedLock"; private final long altTimeout = 1 * 60 * 60 ...
- 自定义可判断选项是否正确listbox
截图如下: 1.实现Converter 获取到listbox,并得到listitem在listbox中的index public class ItemContainerToZIndex ...
- js生成 1-100 不重复随机数
var count=100; var a=new Array(); for(var i=0;i<100;i++){ a[i]=i+1; } a.sort(function(){ return 0 ...
- android-support-xxxx.jar NoClassDefFoundError
当你的项目出现以下红色提示的时候,要小心了,因为很可能因为这个错误而导致解释不通的异常出现. Found 2 versions of android-support-v4.jar in the dep ...
- WebStorm 快捷键收藏
快捷键 Ctrl+/ 或 Ctrl+Shift+/ 注释(// 或者/-/ ) Ctrl+X 或 Ctrl+Y 删除一行 Shift+F6 重构-重命名 Alt+~vcs操作 Alt+~ 7关闭重 ...
- TOMCAT内存大小调整
Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个java虚拟机.JAVA程序启动时JVM都会分配一个初始内存和最大内存给这个应用程序.这个初始内存和最大内存在一定程度都会 ...
- objdump的使用方法和 symbol table的每列的含义
一.objdump的用法 objdump命令的man手册 objdump [-a] [-b bfname| --target=bfdname] [-C] [--debugging] ...
- 万网域名解析到IP地址
进入https://home.console.aliyun.com/#/的阿里云控制台 再自己购买的域名列表里进行操作 添加一个A解析
- 结构体,公用体,枚举类型的sizeof
1)枚举类enum型空间计算 enum只是定义了一个常量集合,里面没有“元素”,而枚举类型是当做int来存储的,所以枚举类型的sizeof值都为4 enum color(red,pink,white, ...
- win下php5.5.12装不上memcache扩展
WAMP这个集成环境里,php目录下有个php.ini,apache/bin下也有一个php.ini,环境使用的是apache下的,改apache