很早之前听说有一种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的更多相关文章

  1. 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] ...

  2. UVA10269 Adventure of Super Mario(Floyd+DP)

    UVA10269 Adventure of Super Mario(Floyd+DP) After rescuing the beautiful princess, Super Mario needs ...

  3. [题解]UVA10269 Adventure of Super Mario

    链接:http://vjudge.net/problem/viewProblem.action?id=24902 描述:由城镇.村子和双向边组成的图,从A+B走到1,要求最短路.有K次瞬移的机会,距离 ...

  4. UVA 10269 Adventure of Super Mario

    看了这里 http://blog.csdn.net/acm_cxlove/article/details/8679230的分析之后自己又按照自己的模板写了一遍,算是对spfa又加深了一步认识(以前真是 ...

  5. UVa 10269 Adventure of Super Mario (Floyd + DP + BFS)

    题意:有A个村庄,B个城市,m条边,从起点到终点,找一条最短路径.但是,有一种工具可以使人不费力的移动L个长度,但始末点必须是城市或村庄.这种工具有k个,每个只能使用一次,并且在城市内部不可使用,但在 ...

  6. UVA-10269 Adventure of Super Mario (dijkstra)

    题目大意:有A个村庄,B个城市,m条边,从起点到终点,找一条最短路径.但是,有一种工具可以使人不费力的移动L个长度,但始末点必须是城市或村庄.这种工具有k个,每个只能使用一次,并且在城市内部不可使用, ...

  7. ZOJ 1232 Adventure of Super Mario (Floyd + DP)

    题意:有a个村庄,编号为1到a,有b个城堡,编号为a+1到a+b.现在超级玛丽在a+b处,他的家在1处.每条路是双向的,两端地点的编号以及路的长度都已给出.路的长度和通过所需时间相等.他有一双鞋子,可 ...

  8. ZOJ2923 Calculate Roads(SPFA上的dp)

    算是学了图dp后的第一次应用吧.题目其实真的是非常不严谨,什么都没说,基本靠猜,而且严格来说数据应该会有爆int的,不过不管那么多啦,思路对了就好- -0 #include<iostream&g ...

  9. zoj1232Adventure of Super Mario(图上dp)

    题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...

随机推荐

  1. Engine许可初始化 - gis开发初步

    当需要对SDE中的要素类和要素数据集(矢量和栅格)进行编辑时,例如在调用IFeatureDataset的CreateFeatureClass方法时,报错提示: The application is n ...

  2. VS默认环境设置

    VS2010的工具菜单-->导入导出设置-->重置所有设置

  3. 锋利的jquery-选择器

    1 jquery $(document).ready(function(){}) 可以简写成 $(function(){})   2 jquery 对象和DOM对像 ① jquery对象和DOM对象不 ...

  4. NetworkInfo 手机中的网络类型

    04-27 21:56:54.442: E/NetworkInfo(26457): NetworkInfo: type: mobile[EDGE], state: DISCONNECTED/IDLE, ...

  5. CentOS 7 终端设置屏幕分辨率

    在grub中我们修改的是/boot/grub/grub.conf,而在grub2中要修改的文件是/boot/grub2/grub.cfg inux16 /vmlinuz-3.10.0-123.el7. ...

  6. Apache 2.4 多站点配置记录

    基于域名的虚拟主机配置 <VirtualHost *:80> DocumentRoot /var/www/cms ServerName www.example.com RewriteEng ...

  7. Jquery显示和隐藏的4种简单方法

    Html代码:  <div class="topicList">  <h3><span>学习天地</span></h3> ...

  8. 如何访问Microsoft Azure Storage

    首先先要创建存储账户 http://www.cnblogs.com/SignalTips/p/4119128.html 可以通过以下的几个方式访问 通过Visual Studio 2013 Commu ...

  9. Microsoft Azure Preview portal 以及Preview Features介绍

    首先mooncake版本并不提供此类功能. 国际版会把将来推出的功能提供Preview,而且是免费的,有想研究未来技术以及的同学可以尝试 通过以下地址进入国际版,往下拉 http://azure.mi ...

  10. Arrays.asList方法总结

    import java.util.Arrays; import java.util.List; /** * * 本类演示了Arrays类中的asList方法 * 通过四个段落来演示,体现出了该方法的相 ...