PAT Advanced 1087 【All Roads Lead to Rome】 (30)

分析:利用map将string与int互相映射,再用Dijkstra+Dfs,注意路径不唯一的时候先取最大happiness,再取经过的城市更少的那条。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
map<int, string> numCity;
map<string, int> cityNum;
vector<int> e[210], tempath, path;
int n, k, tem, tot, cnt = 1, mind = inf, maxh = 0, minl = inf, st = 1, ed = 1;
int happiness[210], cost[210][210], vis[210];
void dijkstra(int st, int ed){
	int d[210];
	memset(d, inf, sizeof d);
	d[st] = 0;
	for(int i = 1; i<=n; i++){
		int u = -1, minn = inf;
		for(int j = 1; j<=n; j++){
			if(d[j] < minn && !vis[j]){
				minn = d[u = j];
			}
		}
		if(u == -1) break;
		vis[u] = 1;
		for(int v = 1; v<=n; v++){
			if(d[u] + cost[u][v] < d[v]){
				d[v] = d[u]+cost[u][v];
			} 
		}
	}
	mind = d[ed];
}
void dfs(int u, int suml, int sumd, int sumh){
	if(sumd > mind) return ;
	else if(sumd == mind && u == ed){
		tot++;
		if(sumh == maxh){
			if(suml < minl){
				minl = suml;
				path = tempath;
			}
		} else if(sumh > maxh){
			minl = suml;
			maxh = sumh;
			path = tempath;
		}
		return;
	}
	for(int i = 0; i<e[u].size(); i++){
		int v = e[u][i];
		if(!vis[v]){
			vis[v] = 1;
			tempath.push_back(v);
			dfs(v, suml+1, sumd+cost[u][v], sumh+happiness[v]);
			tempath.pop_back();
			vis[v] = 0;
		}
	}
}
int main(){
	//freopen("aa.txt", "r", stdin);
	ios::sync_with_stdio(false);
	string start, str, str2;
	cin >> n >> k >> start;
	cityNum[start] = 1;
	numCity[1] = start;
	for(int i = 2; i<n+1; i++){
		cin >> str >> happiness[i];
		cityNum[str] = i;
		numCity[i] = str;
	}
	ed = cityNum["ROM"];
	memset(cost, inf, sizeof cost);
	for(int i = 0; i<k; i++){
		cin >> str >> str2 >> tem;
		int u = cityNum[str], v = cityNum[str2];
		cost[u][v] = cost[v][u] = tem;
		e[u].push_back(v), e[v].push_back(u);
	}
	dijkstra(st, ed);
	memset(vis, 0, sizeof vis);
	vis[st] = 1;
	tempath.push_back(st);
	dfs(st, 0, 0, 0);
	cout << tot << " " << mind << " " << maxh << " " << maxh/minl << '\n';
	for(int i = 0; i<path.size(); i++){
		cout << numCity[path[i]];
		i != path.size()-1 ? cout << "->" : cout << "\n";
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/gq__97/article/details/81989112