1087. All Roads Lead to Rome 解析

条条大路通罗马。

Dijstra+DFS通杀。。。

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <climits>

#define MAX 200

using namespace std;

int n, k;
string st;
map <string, int> city2int;
map <int, string> int2city;

struct Link {
	int len;
	int CityNum;
	Link(int _len, int _CityNum) :len(_len), CityNum(_CityNum) {};
};
struct Node{
	int happiness;
	vector <Link> link;
};

Node m[MAX];
bool isVis[MAX];
vector <int> pre[MAX];
int dis[MAX];

void InitParam() {
	for (int i = 0; i < MAX; i++) {
		isVis[i] = false;
		dis[i] = INT_MAX;
	}
}



void Dijstra(int st) {

	dis[st] = 0;
	for (int i = 0; i < n; i++) {
		int min = INT_MAX, u = -1;
		for (int j = 0; j < n; j++) {
			if (dis[j] < min && !isVis[j]) {
				min = dis[j];
				u = j;
			}
		}

		if (u == -1) return;

		isVis[u] = true;
		for (int j = 0; j < m[u].link.size(); j++) {
			int v = m[u].link[j].CityNum;
			if (!isVis[v]) {
				if (dis[v] > dis[u] + m[u].link[j].len) {
					pre[v].clear();
					pre[v].push_back(u);
					dis[v] = dis[u] + m[u].link[j].len;
				}
				else if(dis[v] == dis[u] + m[u].link[j].len)
					pre[v].push_back(u);
			}
		}
	}
}

struct Ans {
	vector <int> way;
	int sumH;
	bool operator > (const Ans a2) {
		if (sumH != a2.sumH)
			return sumH > a2.sumH;
		else
			return way.size() < a2.way.size();
	}
};
Ans ThisAns, FinAns;
int Count = 0;

void DFS(int u) {
	if (u == city2int[st]) {
		Count++;
		ThisAns.way.push_back(u);
		if (ThisAns > FinAns) {
			FinAns = ThisAns;
		}
		ThisAns.way.pop_back();
		return;
	}

	ThisAns.way.push_back(u);
	int tempSum = ThisAns.sumH;
	ThisAns.sumH += m[u].happiness;
	for (int i = 0; i < pre[u].size(); i++) {
		DFS(pre[u][i]);
	}
	ThisAns.sumH = tempSum;
	ThisAns.way.pop_back();	
}


int main() {
	cin >> n >> k >> st;

	city2int[st] = 0;
	int2city[0] = st;
	m[0].happiness = 0;

	string CityName;
	for (int i = 1; i < n; i++) {
		cin >> CityName;
		city2int[CityName] = i;
		int2city[i] = CityName;
		cin >> m[i].happiness;
	}

	string c1, c2;
	int len;
	for (int i = 0; i < k; i++) {
		cin >> c1 >> c2 >> len;
		m[city2int[c1]].link.push_back(Link(len, city2int[c2]));
		m[city2int[c2]].link.push_back(Link(len, city2int[c1]));
	}

	InitParam();
	Dijstra(city2int[st]);
	DFS(city2int["ROM"]);

	cout << Count << " " << dis[city2int["ROM"]] << " " <<  FinAns.sumH << " " << int(FinAns.sumH / (FinAns.way.size()- 1)) << endl;
	cout << st;
	for (int i = FinAns.way.size() - 2; i >= 0; i--) {
		cout << "->" << int2city[FinAns.way[i]];
	}
	cout << endl;

	return 0;


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值