1087. All Roads Lead to Rome (30)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
using namespace std;

inline int id(char str[]) {
	int n = 0;
	for(int i = 0; i < 3; i ++) {
		n *= 26;
		n += (str[i] - 'A');
	}
	return n;
}

inline char *sid(int cid) {
	static char str[4] = {};
	for(int i = 2; i >= 0; i --) {
		str[i] = cid % 26 + 'A';
		cid /= 26;
	}
	return str;
}

#define N 200

void findpath(int suid, int duid, int map[][N], int n, vector<int> pre[], int &cost) {
	int dist[N] = {};
	int done[N] = {};

	int node = suid;
	done[suid] = 1;
	while(!done[duid]) {
		for(int i = 0; i < n; i ++) {
			if(map[node][i] && !done[i]) {
				int tmpd = dist[node] + map[node][i];
				if(!dist[i] || tmpd < dist[i]) {
					dist[i] = tmpd;
					pre[i].clear();
					pre[i].push_back(node);
				}
				else if(dist[i] == tmpd) {
					pre[i].push_back(node);
				}
			}
		}
		int mind = 0x7fffffff;
		for(int i = 0; i < n; i ++) {
			if(!done[i] && dist[i] && dist[i] < mind) {
				node = i;
				mind = dist[i];
			}
		}
		done[node] = true;
	}
	cost = dist[duid];
}

void checkbest(int suid, int duid, vector<int> pre[], int happy[], int &bh, int ch,
	stack<int> &bp, stack<int> &cp, int &pc) {
	
	cp.push(duid);
	ch += happy[duid];

	if(suid != duid) {

		for(int i = 0; i < pre[duid].size(); i ++) {
			checkbest(suid, pre[duid][i], pre, happy, bh, ch, bp, cp, pc);
		}
	}
	else {
		pc ++;
		if(ch > bh || (ch == bh && ch/(cp.size()-1) > bh/(bp.size()-1))) {
			bh = ch;
			bp = cp;
		}
	}
	cp.pop();
}

int main(int argc, char **argv) {

	int n, m;
	char src[4];
	scanf("%d%d%s", &n, &m, src);

	int cid2uid[26*26*26] = {};
	int uid2cid[N] = {};
	int happy[N] = {};

	int cid = id(src);
	cid2uid[cid] = 0;
	uid2cid[0] = cid;

	for(int i = 1; i < n; i ++) {
		char city[4];
		scanf("%s%d", city, &happy[i]);

		int cid = id(city);
		cid2uid[cid] = i;
		uid2cid[i] = cid;
	}

	int map[N][N] = {{}};
	for(int i = 0; i < m; i ++) {
		char c1[4], c2[4];
		int cost;
		scanf("%s%s%d", c1, c2, &cost);
		int uid1 = cid2uid[id(c1)];
		int uid2 = cid2uid[id(c2)];
		map[uid1][uid2] = cost;
		map[uid2][uid1] = cost;
	}

	int suid = cid2uid[id(src)];
	int duid = cid2uid[id("ROM")];

	vector<int> pre[N];
	int cost;
	findpath(suid, duid, map, n, pre, cost);

	int bh = 0, ch = 0;
	stack<int> bp, cp;
	int pc = 0;
	checkbest(suid, duid, pre, happy, bh, ch, bp, cp, pc);

	printf("%d %d %d %d\n", pc, cost, bh, bh/(bp.size()-1));
	printf("%s", sid(uid2cid[bp.top()]));
	bp.pop();
	while(bp.size()) {
		printf("->%s", sid(uid2cid[bp.top()]));
		bp.pop();
	}
	putchar('\n');

	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值