1087.All Roads Lead to Rome

【题意】
        找出一个图中起始节点到目标节点代价最少并满足其他一些条件的路径

【思路】

        类似的题在PAT里实在碰到太多遍了。。。依然是Dijkstra找最短路径长然后DFS找到所有最短路径并筛选的老套路


#include <iostream>
#include <map>
#include <vector>
#include <cstdio>
#include <string>
#include <stack>
using namespace std;

#define INF 0x0fffffff

map<string,int> name2id;
map<int,string> id2name;
vector<int> happiness,dist;
vector<vector<int>> weight;
stack<int> path;
int n,k,maxHappiness,cityCnt,pathCnt;

bool dfs(int index, int h, int cnt){
	h += happiness[index];
	cnt++;
	if(index==name2id["ROM"]){
		pathCnt++;
		if(h>maxHappiness || (h==maxHappiness && cnt<cityCnt)){
			maxHappiness = h;
			cityCnt = cnt;
			while(!path.empty()){
				path.pop();
			}
			path.push(index);
			return true;
		}
		return false;
	}
	else{
		bool flag = false;
		for(int i=0; i<n; i++){
			if(dist[index]+weight[index][i]==dist[i]){
				if(dfs(i,h,cnt)){
					path.push(index);
					flag = true;
				}
			}
		}
		return flag;
	}
}

int main(int argc, char const *argv[])
{
	cin >> n >> k;

	happiness.resize(n);
	dist.assign(n,INF);
	weight.resize(n);
	for(int i=0; i<n; i++){
		weight[i].assign(n,INF);
	}
	vector<bool> visited;
	visited.assign(n,0);

	string name;
	cin >> name;
	name2id[name] = 0;
	id2name[0] = name;
	happiness[0] = 0;
	for(int i=1; i<n; i++){
		int h;
		cin >> name >> h;
		name2id[name] = i;
		id2name[i] = name;
		happiness[i] = h;
	}

	for(int i=0; i<k; i++){
		string c[2];
		int cost,id[2];

		cin >> c[0] >> c[1] >> cost;
		for(int j=0; j<2; j++){
			id[j] = name2id[c[j]];
		}
		weight[id[0]][id[1]] = weight[id[1]][id[0]] = cost;
	}

	//Dijkstra
	visited[0] = 1;
	dist[0] = 0;
	int index = 0;
	for(int i=1; i<n; i++){
		int min = INF, nextIndex;
		for(int j=1; j<n; j++){
			if(!visited[j]){
				if(dist[index]+weight[index][j]<dist[j]){
					dist[j] = dist[index]+weight[index][j];
				}
				if(dist[j]<min){
					min = dist[j];
					nextIndex = j;
				}
			}
		}
		if(min==INF){
			break;
		}
		index = nextIndex;
		visited[index] =1;
	}

	maxHappiness = -INF;
	cityCnt = INF;
	pathCnt = 0;
	dfs(0,0,-1);
	
	cout << pathCnt << " " << dist[name2id["ROM"]] << " " << maxHappiness << " " << maxHappiness/cityCnt << endl;
	bool first = true;
	while(!path.empty()){
		if(first){
			first = false;
		}
		else{
			cout << "->";
		}
		cout << id2name[path.top()];
		path.pop();
	}

	system("pause");
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值