SRM 583 Div II Level Three:GameOnABoard,Dijkstra最短路径算法

题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12556


用Dijkstra实现,之前用Floyd算法写了一个,结果在2s内算不出结果来。

参考了别人算法,学到了set容器的一个用法,用set省去了查找Dijkstra算法中选择最短路径的那一步,set中的第一个元素就是最小值,用priority queue应该也可以。


#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

#define MAX_SIZE 40
#define INFINITY 100000

#define entry(x, y) make_pair(dd[x][y], make_pair(x, y))

int dijkstra(int x, int y);
vector <string> bcost;

int dd[MAX_SIZE][MAX_SIZE];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int rows, cols;
class GameOnABoard
{
public:
	int optimalChoice(vector <string> cost);
};

int GameOnABoard::optimalChoice(vector<string> cost)
{
	int rows, cols, minL;
	rows = cost.size();
	cols = cost[0].size();
	minL = INFINITY;
	bcost = cost;
	for (int i = 0; i < rows; i++) {
		for (int j = 0; j < cols; j++) {
			minL = min(minL, dijkstra(i, j));
		}
	}

	return minL;
}

int dijkstra(int x, int y)
{
	int i, j, dir, maxC;
	int cus_x, cus_y, next_x, next_y;
	set < pair<int, pair<int, int>> > s;
	rows = bcost.size();
	cols = bcost[0].size();

	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++) {
			dd[i][j] = INFINITY;
		}
	}
	dd[x][y] = bcost[x][y] - '0';
	s.insert(entry(x, y));

	while (!s.empty()) {
		cus_x = s.begin()->second.first;
		cus_y = s.begin()->second.second;
		s.erase(s.begin());

		for (dir = 0; dir < 4; dir++) {
			next_x = cus_x + dx[dir];
			next_y = cus_y + dy[dir];
			if (next_x < 0 || next_x >= rows || next_y < 0 || next_y >= cols) {
				continue;
			}

			if (dd[next_x][next_y] <= dd[cus_x][cus_y] + bcost[next_x][next_y] - '0') {
				continue;
			}
			s.erase( entry(next_x, next_y) );
			dd[next_x][next_y] = dd[cus_x][cus_y] + bcost[next_x][next_y] - '0';
			s.insert( entry(next_x, next_y) );
		}
	}
	maxC = 0;
	for (i = 0; i < rows; i++) {
		for (j = 0; j < cols; j++) {
			maxC = max(maxC, dd[i][j]);
		}
	}
	return maxC;
}
原文地址:https://www.cnblogs.com/snake-hand/p/3151167.html