PAT-A 1003 Emergency

 题目描述

题目场景为:作为一个城市救援队队长,要求你在一个城市发生事故时,以最快的速度赶到目标城市。当到达城市的时间相同时,要从途经的每个城市带上尽可能多的救援队员。

题目给出了一个无向图,图的每个节点代表一个城市,节点之间的边代表城市之间的道路联系。每个节点有一个权重值,代表这个节点所可以调用的救援队人数;每条边有一个权重值,代表两个城市之间的距离。实际上是一个最短路径问题,要求两个城市之间的最短路径的条数,同时在求得的最短路径之中,计算出能够带上的最多的救援人数。

解题思路

一开始用最短路径(dijkstra)写的,后来在网上看到有人用dfs写,反而要简单很多。把两种算法都写了一下,列在下面。

1.最短路径算法

#include <iostream>
#include <cstring>
#include <climits>
#include <vector>
using namespace std;

int cnt=1;
int max_weight=0;//路径最短情况下,可以携带的最多人手

void getResult(vector<vector<int>> &prev,int *weight,int temp,int weight_temp)
{
	if(prev[temp].empty())
		max_weight=max_weight<weight_temp?weight_temp:max_weight;
	else
		cnt+=prev[temp].size()-1;

	for(int i=0;i<prev[temp].size();++i)
		getResult(prev,weight,prev[temp][i],weight_temp+weight[prev[temp][i]]);
}

void dijkstra(int **matrix,int *weight,int size,int st,int end)
{
	int *dist=new int[size];
	for(int i=0;i<size;++i)
		dist[i]=INT_MAX;
	bool *vis=new bool[size];
	memset(vis,false,sizeof(bool)*size);
	vector<vector<int>> prev(size);

	dist[st]=0;
	int temp=st;
	for(int i=0;i<size;++i)
	{
		vis[temp]=true;
		//更新距离
		for(int j=0;j<size;++j)
		{
			if(!vis[j]&&matrix[temp][j]>0)
			{
				if(dist[j]>dist[temp]+matrix[temp][j])
				{
					dist[j]=dist[temp]+matrix[temp][j];
					prev[j].clear();
					prev[j].push_back(temp);
				}
				else if(dist[j]==dist[temp]+matrix[temp][j])
				{
					dist[j]=dist[temp]+matrix[temp][j];
					prev[j].push_back(temp);
				}
			}
		}
		//取得最小值
		int min=INT_MAX;
		for(int j=0;j<size;++j)
		{
			if(!vis[j]&&dist[j]<min)
			{
				min=dist[j];
				temp=j;
			}
		}
	}

	//获得每条路径的权重和,并取得最大权重
	getResult(prev,weight,end,weight[end]);
	cout<<cnt<<" "<<max_weight<<endl;

	delete[] dist,vis;
}

int main()
{
	int num_cities,num_roads,st,end;
	cin>>num_cities>>num_roads>>st>>end;
	int *weight=new int[num_cities];//权重数组,代表每个节点的人手数量
	for(int i=0;i<num_cities;++i)
		cin>>weight[i];
	int **matrix=new int*[num_cities];//关联矩阵,表示各个节点间的联系及距离
	for(int i=0;i<num_cities;++i)
	{
		matrix[i]=new int[num_cities];
		memset(matrix[i],0,sizeof(int)*num_cities);
	}
	for(int i=0;i<num_roads;++i)
	{
		int stTemp,endTemp,dist;
		cin>>stTemp>>endTemp>>dist;
		matrix[stTemp][endTemp]=matrix[endTemp][stTemp]=dist;
	}

	dijkstra(matrix,weight,num_cities,st,end);

	delete[] weight;
	return 0;
}

2 dfs

#include <iostream>
#include <cstring>
#include <climits>
using namespace std;

int cnt=0;
int weight_max=0,dist_min=INT_MAX;

void dfs(int **matrix,int *weight,bool *vis,int size,int st,int end,int distTemp,int weightTemp)
{
	if(st==end)
	{
		if(distTemp<dist_min)
		{
			dist_min=distTemp;
			weight_max=weightTemp;
			cnt=1;
		}
		else if(distTemp==dist_min)
		{
			if(weightTemp>weight_max)
				weight_max=weightTemp;
			++cnt;
		}
	}

	for(int i=0;i<size;++i)
	{
		if(!vis[i]&&matrix[st][i]>0)
		{
			vis[i]=true;
			dfs(matrix,weight,vis,size,i,end,distTemp+matrix[st][i],weightTemp+weight[i]);
			vis[i]=false;
		}
	}
}

int main()
{
	int num_cities,num_roads,st,end;
	cin>>num_cities>>num_roads>>st>>end;
	int *weight=new int[num_cities];//权重数组,代表每个节点的人手数量
	for(int i=0;i<num_cities;++i)
		cin>>weight[i];
	int **matrix=new int*[num_cities];//关联矩阵,表示各个节点间的联系及距离
	for(int i=0;i<num_cities;++i)
	{
		matrix[i]=new int[num_cities];
		memset(matrix[i],0,sizeof(int)*num_cities);
	}
	for(int i=0;i<num_roads;++i)
	{
		int stTemp,endTemp,dist;
		cin>>stTemp>>endTemp>>dist;
		matrix[stTemp][endTemp]=matrix[endTemp][stTemp]=dist;
	}

	bool *vis=new bool[num_cities];
	memset(vis,false,sizeof(bool)*num_cities);
	vis[st]=true;
	dfs(matrix,weight,vis,num_cities,st,end,0,weight[st]);
	cout<<cnt<<" "<<weight_max<<endl;

	delete[] weight;
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值