【PAT】A1087 ALL Roads Leads to Road

Dijkstra+DFS

1) Dijkstra 解决最短路径,以HZH作为输入,得到 到达各个节点的最短路径 的前驱节点数组;

2) DFS 以ROM作为输入,根据前驱节点数组,在每次递归DFS之前,使用数组保留路径,在最终到达递归边界时,根据数组的路径,得到一路上的weight总和

注意:

1)Dijkstra的算法,DFS算法

2)尽量使用全局变量,引用传递参数太费心了。


/* run this program using the console pauser or add your own getch, system("pause") or input loop */
/*
 * Roads_Rome.cpp
 *
 *  Created on: Jan 30, 2020
 *      Author:
 */

/* Solve this by Dijkstra and DFS
 * */

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

typedef vector < vector<int> > Vector2D;
const int CITYNUM = 200;
const int INF = 10000;

int citys_minroute_num[CITYNUM];
int citys_weight[CITYNUM];
int citys_distance[CITYNUM];
int citys_path_num[CITYNUM];
bool citys_visit[CITYNUM] ={false};

map <int,string> int2str_map;
map <string,int> str2int_map;

void string2int(int &city_index,string city_name){
	map<string, int>::iterator  iter= str2int_map.find(city_name);
	if (iter == str2int_map.end()) {
		str2int_map[city_name] = city_index;
		int2str_map[city_index] = city_name;
	} else {
		city_index = iter->second;
	}
}

string int2string(int &city_id){
	map<int, string>::iterator iter = int2str_map.find(city_id);
	return iter->second;
}

void Dijkstra(int city_num,int city_start,Vector2D &city_map,Vector2D &city_pre){
	fill(citys_distance,citys_distance+CITYNUM,INF);
	citys_distance [0] = 0;
	for (int i=0;i<city_num;i++){
		int min_distance  = INF;
		int select_id = -1;
		for(int j=0;j<city_num;j++){
			if((citys_visit[j]==false)&&(citys_distance[j]<INF))
			{
				if(citys_distance[j]<min_distance){
					select_id = j;
					min_distance = citys_distance[j];
				}
			}
		}

		if(select_id<0) return;
		citys_visit[select_id] = true;
		for (int j=0;j<city_num;j++){
			// In previous version, wrong code citys_visit[select_id]==flase
			if(citys_visit[j]==false &&city_map[select_id][j]!=INF){
				int city_distance_tmp = citys_distance[select_id]+city_map[select_id][j];
				if(city_distance_tmp<citys_distance[j]){
					citys_distance[j] = city_distance_tmp;
					citys_path_num[j] = citys_path_num [select_id];
					city_pre[j].push_back(select_id);
				}else if (city_distance_tmp==citys_distance[j]) {
					citys_path_num[j]=citys_path_num[select_id]+1;
					city_pre[j].push_back(select_id);
				}
			}
		}
	}
}

void DFS(int &path_num,int city_id, int &max_avg,int *citys_weight,
		vector<int> &path,int &citys_weight_sum,Vector2D &city_pre,vector<int> &path_record){
	// In this part 0, is the start city, which should be input parameter
	if(city_id==0){
		path_record.push_back(city_id);
		path_num++;
		int tmp_weight_sum=0;
		for (int i= path_record.size()-1;i>=0;i--){
			int city_id = path_record[i];
			tmp_weight_sum +=citys_weight[city_id];
		}

		if(tmp_weight_sum>citys_weight_sum){
			citys_weight_sum  = tmp_weight_sum;
			path = path_record;
			max_avg = citys_weight_sum/(path.size()-1);
		}else if ( (tmp_weight_sum==citys_weight_sum) && ( path.size()>path_record.size() ) ){
			path = path_record;
			max_avg =citys_weight_sum/(path.size()-1);
		}
		path_record.pop_back();
		return;
	}

	path_record.push_back(city_id);
	for (int i=0;i<city_pre[city_id].size();i++){
		DFS(path_num,city_pre[city_id][i],max_avg,citys_weight,path,citys_weight_sum,city_pre,path_record);
	}
	path_record.pop_back();

}

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

	int city_num=0, road_num=0,city_index=0;
	string start_city;

	cin>>city_num>>road_num>>start_city;
    int city_num_tmp = city_num;
	Vector2D city_map (city_num,vector<int>(city_num,INF));
	Vector2D city_pre(city_num);
	vector<int> city_path_num (city_num);

	string city_name;
	int city_weight;

	string2int(city_index,start_city);
	citys_weight[city_index] = 0;
	
	city_num--;

	while(city_num--) {
		cin>>city_name>>city_weight;
		city_index++;
		string2int(city_index,city_name);
		citys_weight[city_index] = city_weight;
	}
	
	city_num = city_num_tmp;

	string cityA, cityB;
	int cityA_id,cityB_id,road_length;
	while(road_num--){
		cin>>cityA>>cityB>>road_length;

		string2int(cityA_id,cityA);
		string2int(cityB_id,cityB);

		city_map[cityA_id][cityB_id] = road_length;
		city_map[cityB_id][cityA_id] = road_length;
	}

	printf("city_num %d\n",city_num);
	Dijkstra(city_num,0,city_map,city_pre);

	int path_num=0,rom_id,max_avg=0,citys_weight_sum = 0;
	vector<int> path,path_record;
	string2int(rom_id,"ROM");
	
	for(int i=0; i<city_num;i++){
		for(int j=0;j<city_pre[i].size();j++){
			printf("city %d city_pre %d\n",i,city_pre[i][j]);
		}
	}
	DFS(path_num,rom_id,max_avg,citys_weight,path,citys_weight_sum,city_pre,path_record);

	cout<<path_num<<" "<<citys_distance[rom_id]<<" "<<citys_weight_sum<<" "<<int(max_avg)<<endl;

	for (int i = path.size()-1;i>=0;i--){
		cout<<int2string(path[i]);
		if(i>0)cout<<"->";
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值