1. 程式人生 > 實用技巧 >PAT - 甲級 - 1087 All Roads Lead to Rome

PAT - 甲級 - 1087 All Roads Lead to Rome

Nothing to fear


種一棵樹最好的時間是十年前,其次是現在!

那些你早出晚歸付出的刻苦努力,你不想訓練,當你覺的太累了但還是要咬牙堅持的時候,那就是在追逐夢想,不要在意終點有什麼,要享受路途的過程,或許你不能成就夢想,但一定會有更偉大的事情隨之而來。 mamba out~


人一我十,人十我百,追逐青春的夢想,懷著自信的心,永不言棄!

All Roads Lead to Rome

考點: Dijkstra 求最短路 + dijkstra記錄路徑 + dfs + map對映

題目大意

給你一個起點,和固定終點求出,起點到終點的最短路徑的條數和起點道終點的最短距離,找到開心值最大的路徑,如果不唯一,則目標路徑為開心值平均值最大的那一條路徑。

分析

老套路了 就不分析了

需要注意的點:

完整程式碼

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <map>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;
const int N = 205;
int n , k , weight[N] , key = 1;
int e[N][N] , romid , dis[N] , vis[N];
string start;
map<string,int> m;
map<int,string> ma;
priority_queue<pair<int,int> > q;
vector<int> pre[N] , path;
/*
輸出內容:
1. 最短路徑的條數
2. 最短路徑的cost
3. 所選出的路徑的最大的開心值
4. 選出路徑的平均開心值
5. 輸出整條路經
*/
int roadcnt , cost , maxhapp = -1 ,averhapp = 0;
void dfs(int now,vector<int> tpath)
{
	if(now == m[start])
	{
		roadcnt++;
		int happ = 0, len = tpath.size();
		for(int i = 0;i < len;i ++)
		{
			happ += weight[tpath[i]];
		}
		int aver = happ / len;
		if(happ > maxhapp)
		{
			maxhapp = happ;
			path = tpath;
			averhapp = aver;
		}else if(happ == maxhapp && aver > averhapp)
		{
			path = tpath;
			averhapp = aver;
		}
	}
	for(int i = 0;i < pre[now].size();i++)
	{
		tpath.push_back(now);
		dfs(pre[now][i] , tpath);
		tpath.pop_back();
	}
}
void Dijkstra(int s)
{
	memset(dis , 0x3f , sizeof dis);
	memset(vis , 0 , sizeof vis);
	dis[s] = 0;
	q.push({0 , s});
	while(!q.empty())
	{
		int x = q.top().second;q.pop();
		if(vis[x])continue;
		vis[x] = 1;
		for(int i = 1;i < key;i ++)
		{
			int y = i, w = e[x][i];
			if(vis[y])continue;
			if(dis[y] > dis[x] + w)
			{
				pre[y].clear();
				pre[y].push_back(x);
				dis[y] = dis[x] + w;
				q.push({-dis[y] , y});
			}else if(dis[y] == dis[x] + w){
				pre[y].push_back(x);
			}
		}
	}
}
int main()
{
	memset(e , 0x3f , sizeof e);
	cin >> n >> k >> start;
	string s;int w;m[start] = key++;
	for(int i = 1;i < n;i ++)
	{
		cin >> s >> w;
		m[s] = key;ma[key] = s;
		if(s == "ROM")romid = key;
		weight[key++] = w;
	}
	string a , b;
	for(int i = 0;i < k;i ++)
	{
		cin >> a >> b >> w;
		int nx = m[a] , ny = m[b];
		e[nx][ny] = e[ny][nx] = w;
	}
	Dijkstra(1);
	dfs(romid , vector<int> ());
	cout << roadcnt << " " << dis[romid] << " ";
	cout << maxhapp << " " << averhapp << endl;
	cout << start;
	for(int i = path.size() - 1;i >=0 ;i --)
	{
		cout << "->" << ma[path[i]];
	}
	return 0;
}