UVA 10269 Adventure of Super Mario
看了这里 http://blog.csdn.net/acm_cxlove/article/details/8679230的分析之后自己又按照自己的模板写了一遍,算是对spfa又加深了一步认识(以前真是只会用,没想太多)。
又来当一次搬运工,一点点进步。
题意是这样的:A个村庄,B个城堡,共有K次穿越的机会,且不能经过城堡或者穿越距离必须不超过L,否则必须停下来,当然,不能再道路中间停下来。
按照大大的思路是这样做的:对于每出队的一个结点u,均有两种方式继续走下去,一中是使用一次穿越,另一种是不使用。这样对于使用穿越的情况,必须考虑所有满足d[u][v]<=L的点v,然后dp[v][k+1] = min(dp[v][k+1],dp[u][k])转移方程,其中dp[u][k]表示从起点A+B走到u使用k次穿越经过的最小距离;对于不使用穿越的情况就和普通spfa一样转移。
然后怎样判断由一个节点到另一个节点能够满足d[u][v]<=L呢,这中间会涉及到城堡不能穿越,可以求出使用spfa求出(i,j)之间的最短距离,对于j是城堡的时候就不把j入队,这样中间有城堡的两个节点d[i][j]是不能直接穿越的,也就是d[i][j] == inf.
然后下面是我写的代码:
(思路也可以去原po那里看)
#include <iostream>
#include <cstdio>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define esp 1e-6
#define pb push_back
#define in freopen("in.txt", "r", stdin);
#define out freopen("out.txt", "w", stdout);
#define print(a) printf("%d\n",(a));
#define bug puts("********))))))");
#define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef vector<int>:: iterator IT;
#define N 2000
#define INF 200000
struct EDGE
{
int i, c;
EDGE *ani,*next;
} *Edge[N], E[INF];
int d[N][N], inq[N], dp[N][];
int cnt, A, B, M, L, K;
void add(int i, int j, int c, EDGE &e1, EDGE &e2)
{
e1.i = j, e1.c = c, e1.ani = &e2, e1.next = Edge[i], Edge[i] = &e1;
e2.i = i, e2.c = c, e2.ani = &e1, e2.next = Edge[j], Edge[j] = &e2;
cnt += ;
}
void init(void)
{
cnt = ;
memset(Edge, , sizeof(Edge));
// memset(d, 0x0f, sizeof(d));
}
void preprocess(void)
{
memset(d, 0x3f, sizeof(d));
for(int i = ; i <= A + B; i++)
{
queue<int> q;
memset(inq, , sizeof(inq));
inq[i] = ;
d[i][i] = ;
q.push(i);
while(!q.empty())
{
int u = q.front();
int v;
q.pop();
inq[u] = ;
for(EDGE * p = Edge[u]; p; p = p->next)
if(d[i][v = p->i] > d[i][u] + p->c)
{
if(d[i][v] = d[i][u] + p->c, v <= A && !inq[v])
inq[v] = , q.push(v);
}
}
}
}
void spfa(int s, int end)
{
memset(dp, 0x3f, sizeof(dp));
memset(inq, , sizeof(inq));
queue<int> q;
inq[s] = ;
dp[s][] = ;
q.push(s);
while(!q.empty())
{
int u = q.front(), v;
q.pop();
inq[u] = ;
for(EDGE *p = Edge[u]; p; p = p->next)
for(int k = ; k <= K; k++)
if(dp[u][k] < inf)
{
if(dp[v = p->i][k] > dp[u][k] + p->c)
if(dp[v][k] = dp[u][k] + p->c, !inq[v])
inq[v] = , q.push(v);
if(k - K)
{
for(v = ; v <= A + B; v++)
// if(dp[u][k] < inf)
if(d[u][v] <= L && dp[u][k] < dp[v][k+])
if(dp[v][k+] = dp[u][k], !inq[v])
inq[v] = , q.push(v);
}
}
}
}
int main(void)
{ int T;
for(int t = scanf("%d", &T); t <= T; t++)
{
init();
scanf("%d%d%d%d%d", &A, &B, &M, &L, &K);
for(int i = ; i <= M; i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
add(u, v, w, E[cnt], E[cnt + ]);
}
preprocess();
spfa(A+B, );
int ans = inf;
for(int k = ; k <= K; k++)
ans = min(dp[][k], ans);
printf("%d\n", ans);
}
return ;
}
UVA 10269 Adventure of Super Mario的更多相关文章
- UVa 10269 Adventure of Super Mario (Floyd + DP + BFS)
题意:有A个村庄,B个城市,m条边,从起点到终点,找一条最短路径.但是,有一种工具可以使人不费力的移动L个长度,但始末点必须是城市或村庄.这种工具有k个,每个只能使用一次,并且在城市内部不可使用,但在 ...
- UVA10269 Adventure of Super Mario(Floyd+DP)
UVA10269 Adventure of Super Mario(Floyd+DP) After rescuing the beautiful princess, Super Mario needs ...
- 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] ...
- ZOJ1232 Adventure of Super Mario spfa上的dp
很早之前听说有一种dp是在图上的dp,然后是在跑SPFA的时候进行dp,所以特地找了一题关于在SPFA的时候dp的. 题意:1~a是村庄 a+1~a+b是城堡,存在m条无向边.求由a+b->1的 ...
- 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处.每条路是双向的,两端地点的编号以及路的长度都已给出.路的长度和通过所需时间相等.他有一双鞋子,可 ...
- [题解]UVA10269 Adventure of Super Mario
链接:http://vjudge.net/problem/viewProblem.action?id=24902 描述:由城镇.村子和双向边组成的图,从A+B走到1,要求最短路.有K次瞬移的机会,距离 ...
- zoj1232Adventure of Super Mario(图上dp)
题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...
- HDU 4417 Super Mario(主席树求区间内的区间查询+离散化)
Super Mario Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
随机推荐
- hasLayout与Block formatting contexts的学习(下)
BFC布局规则: 内部的Box会在垂直方向,一个接一个地放置. Box垂直方向的距离由margin决定.属于同一个BFC的两个相邻Box的margin会发生重叠 每个元素的margin box的左边, ...
- linux下挂载iso镜像的方法
新建目录/mnt/cdrom 执行命令 mount /dev/cdrom /mnt/cdrom [root@ocdp1 cdrom]# mount /dev/cdrom /mnt/cdrom moun ...
- [python] 高效使用assert
Places to consider putting assertions: checking parameter types, classes, or values checking data st ...
- 【html】【9】div布局[div层叠]
让DIV重叠并按想要顺序重叠需要CSS来实现,即CSS绝对定位进行实现. 重叠样式需要主要CSS样式解释1.z-index 重叠顺序属性2.position:relative和position:abs ...
- 手把手教你写电商爬虫-第三课 实战尚妆网AJAX请求处理和内容提取
版权声明:本文为博主原创文章,未经博主允许不得转载. 系列教程: 手把手教你写电商爬虫-第一课 找个软柿子捏捏 手把手教你写电商爬虫-第二课 实战尚妆网分页商品采集爬虫 看完两篇,相信大家已经从开始的 ...
- redis_笔记
1.redis是什么 这个问题的结果影响了我们怎么用redis.如果你认为redis是一个key value store,那可能会用它来 代替mysql:如果认为它是一个可以持久化的cache,可能只 ...
- php的运行环境介绍
php软件已下载在我的百度云:页面底部有地址,如有需要欢迎下载! 一:如何让php环境运行php代码? 直接使用php软件直接运行代码文件中的php代码 在B/S结构中让Apache使用php软件运行 ...
- Sublime Text 3插件安装方法
安装Sublime Tex 3t插件的方法: 按快捷键Ctrl + ~ 调出console 粘贴以下代码到console并回车: import urllib.request,os; pf = 'Pac ...
- Oracle 自连接 / 外连接 / 子查询
--连接查询的三种格式 select ename, deptno,dname from emp natural join dept; select ename, deptno,dname from e ...
- Application.StartupPath同System.Environment.CurrentDirectory区别
System.Windows.Forms.Application.StartupPath:获取启动了应用程序的可执行文件的路径,不包括可执行文件的名称. System.Environment.Curr ...