PAT甲级1111. Online Map

PAT甲级1111. Online Map

题意:

输入我们当前的位置和目的地,一个在线地图可以推荐几条路径。现在你的工作是向你的用户推荐两条路径:一条是最短的,另一条是最快的。确保任何请求存在路径。

输入规格:

每个输入文件包含一个测试用例。对于每种情况,
第一行给出两个正整数N(2 <= N <= 500),M分别是地图上街道交叉路口的总数和街道数。然后M行跟随,每个描述一个街道的格式:

V1 V2单程长度时间

其中V1和V2是街道两端的索引(从0到N-1);一-
方式是1,如果街道从V1到V2是单向的,或者如果没有,则为0;长度是街道的长度;时间是通过街道的时间。

最后给出一对源和目的地。

输出规格:

对于每种情况,首先打印距离为D的源到目的地的最短路径,格式如下:
距离= D:源 - > v1 - > ... - >目的地

然后在下一行打印总时间最快的路径T:

时间= T:源 - > w1 - > ... - >目的地

如果最短路径不唯一,则输出最短路径中最快的路径,这被保证是唯一的。如果最快的路径不是唯一的,
输出通过最少交叉路口的路口,这被保证是唯一的。

如果最短和最快的路径相同,请以以下格式打印一行:

距离= D;时间= T:源 - > u1 - > ... - >目的地

思路:

Dijkstra + dfs.写了一个小时,有点慢。

ac代码:

C++

// pat1111.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#include<stdio.h>
#include<map>
#include<cmath>
#include<unordered_map>
#include<unordered_set>

using namespace std;

int n, m;
int starting, destination;
int mymap[501][501];
int mytime[501][501];
int visit[501];
int len[501];
int vec[501];
int disway[501];
int timeway[501];
int temp[501];
int short_time = -1;
int time_len = -1;
int dlen = 0,time_dis = 0;

void Dijkstra()
{
	int now = -1;

	memset(visit, 0, sizeof(visit));
	memset(len, -1, sizeof(len));
	len[starting] = 0;
	while (1)
	{
		now = -1;
		for (int i = 0; i < n; i++)
		{
			if (!visit[i] && len[i] != -1 && (now == -1 || len[i] < len[now])) now = i;
		}
		if (now == -1) break;
		visit[now] = 1;
		for (int i = 0; i < n; i++)
		{
			if (!visit[i] && mymap[now][i] && (len[i] == -1 || mymap[now][i] + len[now] < len[i] ))
				len[i] = mymap[now][i] + len[now];
		}
	}

	memset(vec, -1, sizeof(vec));
	memset(visit, 0, sizeof(visit));
	vec[starting] = 0;
	while (1)
	{
		now = -1;
		for (int i = 0; i < n; i++)
		{
			if (!visit[i] && vec[i] != -1 && (now == -1 || vec[i] < vec[now])) now = i;
		}
		if (now == -1) break;
		visit[now] = 1;
		for (int i = 0; i < n; i++)
		{
			if (!visit[i] && mytime[now][i] && (vec[i] == -1 ||mytime[now][i] + vec[now] < vec[i]))
				vec[i] = mytime[now][i] + vec[now];
		}
	}

}

void dfs(int cur, int dis, int time, int pos)
{
	if (dis > len[destination] && time > vec[destination]) return;
	if (dis == len[destination] && cur == destination)
	{
		if (short_time == -1 || time < short_time)
		{
			short_time = time;
			dlen = pos;
			for (int i = 0; i < pos; i++)
				disway[i] = temp[i];
		}
	}
	if (time == vec[destination] && cur == destination)
	{
		if (time_len == -1 || pos < time_len)
		{
			time_len = pos;
			time_dis = dis;
			for (int i = 0; i < pos; i++)
				timeway[i] = temp[i];
		}
	}

	for (int i = 0; i < n; i++)
	{
		if (!visit[i] && mymap[cur][i])
		{
			temp[pos] = i;
			dfs(i, dis + mymap[cur][i], time + mytime[cur][i], pos + 1);
		}
	}

}

int main()
{
	//input
	scanf("%d %d", &n, &m);
	int v1, v2, is_one, l, t;
	for (int i = 0; i < m; i++)
	{
		scanf("%d %d %d %d %d", &v1, &v2, &is_one, &l, &t);
		if (is_one)
		{
			mymap[v1][v2] = l;
			mytime[v1][v2] = t;
		}
		else
		{
			mymap[v1][v2] = mymap[v2][v1] = l;
			mytime[v1][v2] = mytime[v2][v1] = t;
		}
	}
	scanf("%d %d", &starting, &destination);

	Dijkstra();

	memset(visit, 0, sizeof(visit));
	//temp[0] = starting;
	dfs(starting,0,0,0);

	if (time_dis == len[destination] && short_time == vec[destination])
	{
		printf("Distance = %d; Time = %d: %d", time_dis, short_time,starting);
		// -> 2 -> 5"
		for (int i = 0; i < time_len; i++)
			printf(" -> %d", timeway[i]);
		printf("
");
	}
	else
	{
		printf("Distance = %d: %d", len[destination], starting);
		for (int i = 0; i < dlen; i++)
			printf(" -> %d", disway[i]);
		printf("
");

		printf("Time = %d: %d", vec[destination], starting);
		for (int i = 0; i < time_len; i++)
			printf(" -> %d", timeway[i]);
		printf("
");
	}

    return 0;
}


原文地址:https://www.cnblogs.com/weedboy/p/7346564.html