HDU 1548 A strange lift

传送门

最短路。
有一个奇怪的电梯,每个楼层有两个数,分别代表从这层坐电梯能往上跑几层或能往下跑几层,层数只在1~N之间生效。问你给定的两层作为出发和到达点,最少坐几次电梯能到。
隐含的建图,图上的边的权值是1,代表坐一次电梯,边的两个端点代表两个层,注意是有向边。

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

const int INF = 1e9;
const int MAXN = 205;
int N, A, B;
int g[MAXN][MAXN];
int dis[MAXN];
bool vis[MAXN];

void dijkstra(int s)
{
	dis[s] = 0;
	for (int i = 0; i < N; i++)
	{
		int u = -1, mind = INF;
		for (int j = 1; j <= N; j++)
		{
			if (!vis[j] && dis[j] < mind)
			{
				mind = dis[j];
				u = j;
			}
		}
		if (u == -1) return;
		vis[u] = 1;
		for (int j = 1; j <= N; j++)
		{
			if (!vis[j] && g[u][j] != -1)
			{
				if (dis[u] + g[u][j] < dis[j])
					dis[j] = dis[u] + g[u][j];
			}
		}
	}
	return;
}

int main()
{
	int x;
	for (; ~scanf("%d", &N);)
	{
		if (N == 0) break;
		scanf("%d%d", &A, &B);

		memset(g, -1, sizeof g);
		fill(dis + 1, dis + N + 1, INF);
		memset(vis, 0, sizeof vis);

		for (int i = 1; i <= N; i++)
		{
			scanf("%d", &x);
			if (x == 0) continue;
			if (i - x >= 1) g[i][i - x] = 1;  // 单向边  没有else情况,小于1不等价于能到1
			if (i + x <= N) g[i][i + x] = 1;
		}
		dijkstra(A);
		if (dis[B] == INF) printf("-1\n");
		else printf("%d\n", dis[B]);
	}

    return 0;
}

posted @ 2019-03-23 13:36  CrossingOver  阅读(72)  评论(0编辑  收藏  举报