【PAT Advanced Level】1018. Public Bike Management (30)

這題還是比較有難度的。題目中要紀錄的東西比較多,比較繁瑣。

這題我考慮先用Dijkstra算法計算單源最短路徑,在計算過程中紀錄每個點的最短路徑的前序(如果最短路徑有多條,每個前序都需要紀錄),然後再遞歸深搜出具有最少攜帶自行車數量的路徑。

這題還有幾個點沒過,先放着吧,感覺整體思路沒什麼問題。

#include <iostream>
#include <memory.h>
#include <fstream>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

const int maxInt = 0x7fffffff;
const int maxStation = 501;
int road[501][501];
int bikeCount[501];
bool visited[501];
int capacity, stationNum, proStation, roadsNum;



struct node
{
	int index;
	int minDistance;
	vector<int> preNode;
	node(int i, int minDistance) : index(i), minDistance(minDistance) {}
};
vector<node> q;
vector<node> s;
int minBike = maxInt;
vector<int> result;

bool cmp(const node &n1, const node &n2)
{
	return n1.minDistance > n2.minDistance;
}
bool cmpbyIndex(const node &n1, const node &n2)
{
	return n1.index > n2.index;
}

void Dijkstra()
{
	s.push_back(node(0, 0));
	for(int i = 1; i <= stationNum; i++)
		s.push_back(node(i, maxInt));
	while (!s.empty())
	{
		make_heap(s.begin(), s.end(), cmp);
		pop_heap(s.begin(), s.end(), cmp);
		node tmp = s.back();
		s.pop_back();
		for(int i = 0; i < s.size(); i++)
		{
			if(road[tmp.index][s[i].index])
			{
				if(tmp.minDistance + road[tmp.index][s[i].index] < s[i].minDistance)
				{
					s[i].minDistance = tmp.minDistance + road[tmp.index][s[i].index];
					s[i].preNode.clear();
					s[i].preNode.push_back(tmp.index);
				}
				else if(tmp.minDistance + road[tmp.index][s[i].index] == s[i].minDistance)
					s[i].preNode.push_back(tmp.index);
			}
		}
		q.push_back(tmp);
	}
}



int getPath(int index, int cur, vector<int> path)
{
	const int need = bikeCount[proStation] - capacity/2;
	sort(s.begin(), s.end(), cmpbyIndex);
	if(index == 0)
	{
		if(abs(cur + need + 5) < abs(minBike + need + 5))
		{
			minBike = cur;
			result = path;
		}
		return 0;
	}
	for(int i = 0; i < q[index].preNode.size(); i++)
	{
		path.push_back(q[index].preNode[i]);
		getPath(q[index].preNode[i], bikeCount[q[index].preNode[i]] - capacity/2 + cur, path);
		path.pop_back();
	}
}

int main()
{
	fstream cin("a.txt");

	cin>>capacity>>stationNum>>proStation>>roadsNum;
	for(int i = 1; i <= stationNum; i++)
		cin>>bikeCount[i];
	for(int i = 0; i < roadsNum; i++)
	{
		int row, colunm, tmp;
		cin>>row>>colunm>>tmp;
		road[row][colunm] = road[colunm][row] = tmp;
	}
	memset(visited, 0, sizeof(visited)/sizeof(bool));



	Dijkstra();

	getPath(proStation, 0, vector<int>());
	//system("pause");
	int tmp = bikeCount[proStation] + minBike;
	if(tmp < 0)
		cout<<abs(tmp)<<" ";
	else cout<<0<<" ";
	
	reverse(result.begin(), result.end());
	for (int i = 0; i < result.size(); i++)
	{
		cout<<result[i]<<"->";
	}
	cout<<proStation<<" ";
	if(tmp > 0)
		cout<<tmp<<endl;
	else cout<<0<<endl;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章