UVa10356 - Rough Roads(Dijkstra)

本文介绍了一种基于迪杰斯特拉算法的改进方法,用于解决特定条件下的最短路径问题。该方法通过调整状态来应对步行与骑行交替的路径规划挑战。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

After he bought the tri-cyclelast year, Shaon went to visit his grandfather's house in a remote part of Bangladesh.He wanted to ride the cycle in quiet, rush-free rural roads. But when hereached the gate of the village of his grandfather, his found his plan useless.The roads are too rough to ride the cycle comfortably. If he rides the cyclefrom one junction to another, his toe would become too tired to push thepaddles in the next part of his journey. He just has to carry the cycle on hisback to reach next junction. After that, he will be able to ride the bikeagain. This would go on until he reaches his grandfather's house. But hedoesn't want to knock his grandfather's door with a cycle on his back. So hemust travel the last roadriding the cycle. He also decided to start hisjourney by carrying the cycle on his back, not by riding it.

 

Can you find out the shortest wayto reach his grandfather's house?

The Input

Input consists of several datasets and is terminated byend of file. The first line of each test case contains two integers:n(the number of junctions, 1 < n < 501) and r (the number ofbi-directional roads connecting these junctions). The junctions are numberedwith 0, 1, ...,n-1. The gate of the village and the grandfather's houseis situated at junctions 0 andn-1 respectively. Each of the next rlines (one for each road) contains three non-negative integers: twojunction-numbers that the corresponding road connects and the length of theroad in kilometers. A road always connects two different junctions. Length of aroad is not more than 20km and not less than 1km.

 

TheOutput

For each dataset, print the set number (1, 2,...) ina line followed by the length of the shortest path. However, if it is notpossible to reach there in the specified way, print a '?'.

Sample Input

3 3

0 1 10

0 2 10

1 2 10

4 4

0 1 10

0 2 10

1 2 10

2 3 10

Sample Input

Set #1

20

Set #2

20

题意:A点到B点之间有n段线路,当前一段跟是走过来时,下一段路就是骑车。要求第一段路是走,最后一段路是骑车,求以这种方式行进的最短距离

思路:用Dijkstra算法,原始的算法是用一维数组d[i]表示到达i点的最短路径。现在因为到达i点有两种状态,是以走路的形式到达i点还是骑车方式到达i点,所以这里用二维数组d[i][2]表示到达i点的最短路径, 用d[i][0]表示以走路方式到达,d[i][1]表示以骑车方式到达

#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int MAXN = 510;
const int INF = 0x3f3f3f3f;

struct Edge
{
	int from, to, w;
} edges[MAXN * MAXN];

struct HeapNode
{
	int u, d, status;
	bool operator < (const HeapNode &other) const
	{
		return d > other.d;
	}
};

int head[MAXN];
int Next[MAXN * MAXN];
int n, r;
int e;
int d[MAXN][2];
bool vis[MAXN][2];
int cas = 1;

int input()
{
	if (scanf("%d%d", &n, &r) != 2) return 0;
	
	memset(head, -1, sizeof(head));
	e = 0;
	for (int i = 0; i < r; i++) {
		int from, to, w;
		scanf("%d%d%d", &from, &to, &w);
		edges[e].from = from;
		edges[e].to = to;
		edges[e].w = w;
		Next[e] = head[from];
		head[from] = e++;
		edges[e].from = to;
		edges[e].to = from;
		edges[e].w = w;
		Next[e] = head[to];
		head[to] = e++;
	}
	return 1;
}

void solve()
{
	memset(d, 0x3f, sizeof(d));
	memset(vis, false, sizeof(vis));
	d[0][1] = 0;
	
	priority_queue<HeapNode> q;
	q.push((HeapNode){0, 0, 1});
	
	while (!q.empty()) {
		HeapNode node = q.top(); q.pop();
		int u = node.u;
		int status = node.status;
		if (vis[u][status]) continue;
		vis[u][status] = true;
		for (int v = head[u]; v != -1; v = Next[v]) {
			int w = edges[v].w;
			int to = edges[v].to;
			if (d[u][status] + w < d[to][1 - status]) {
				d[to][1 - status] = d[u][status] + w;
				q.push((HeapNode){to, d[to][1 - status], 1 - status});
			}
		}
	}
	
	printf("Set #%d\n", cas++);
	if (d[n - 1][1] == INF) {
		printf("?\n");
	} else {
		printf("%d\n", d[n - 1][1]);
	}
	
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif

	while (input()) {
		solve();
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值