您的位置:首页 > 其它

Adventure of Super Mario UVA - 10269

2017-05-26 09:05 387 查看

Adventure of Super Mario UVA - 10269

图论·最短路

http://blog.csdn.net/keshuai19940722/article/details/16920629

题目大意:

马里奥就出桃子之后,要返回自己所居住的村子标号为1,给出A 和 B表示有A个村子和B个城堡,大魔王所居住的城堡A + B,1 ~A为村子,A + 1 ~ B为城堡。现在有m条路,连接着村子、城堡;每条路有它的距离;然后马里奥可以使用k次魔法,可以从一个地方瞬间移动到另外一个地方(不可以在路中间停,并且距离不超过l);并且使用魔法的时候不能穿过城堡。问说玛丽奥最少花费的时间。

题解:

先用Floyd求出任意两点间只经过村庄的最短距离。

(最外层中间节点循环到A即可)

然后dp[i][j]表示到达i使用j次魔法的最短距离。

分层图最短路即可。

Code:

#include <stdio.h>
#include <string.h>

#define min(a,b) (a)<(b)?(a):(b)

const int N = 105;
const int K = 15;
const int INF = 0x3f3f3f3f;

int A, B, n, m, l, k;
int dp
[K], g

, f

, vis
[K];

void init() {
scanf("%d%d%d%d%d", &A, &B, &m, &l, &k);
n = A + B;

memset(g, INF, sizeof(g));
memset(f, INF, sizeof(f));
memset(vis, 0, sizeof(vis));

int a, b, c;
for (int i = 0; i < m; i++) {
scanf("%d%d
4000
%d", &a, &b, &c);
g[a][b] = g[b][a] = f[a][b] = f[b][a] = c;
}

for (int i = 1; i <= n; i++)
f[i][i] = 0;
}

void Floyd() {

for (int t = 1; t <= A; t++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
f[i][j] = min(f[i][j], f[i][t] + f[t][j]);
}

void solve() {
memset(dp, INF, sizeof(dp));
dp
[0] = 0;

m = n * (k + 1);
int u, v, c;

for (int t = 0; t < m; t++) {

c = INF;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) {
if (!vis[i][j] && dp[i][j] < c) {
u = i, v = j;
c = dp[i][j];
}
}
}

vis[u][v] = 1;

for (int i = 1; i <= n; i++) {
if (f[u][i] <= l && dp[i][v + 1] > dp[u][v]) {
dp[i][v + 1] =  dp[u][v];
vis[i][v + 1] = 0;
}

if (dp[i][v] > dp[u][v] + g[u][i]) {
dp[i][v] = dp[u][v] + g[u][i];
vis[i][v] = 0;
}
}
}

printf("%d\n", dp[1][k]);
}

int main () {
int cas;
scanf("%d", &cas);
while (cas--) {
init();
Floyd();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: