PAT 1003 Emergency (25 分)

1003 Emergency (25 分)

易错点以及思路的梳理

总体上来说就是dijkstra算法的变形,也就是说原始的版本判断是否是加入边的时候,只是考虑到达源点的距离大小来进行更新,在本题中加入了第二条判断法制,也就是考虑该城市的队伍数量。

具体来说

1、记录不同的最短路径
2、在选取的路径长度相同时,进一步考虑所能召集的城市队伍数量

代码展示

#include<iostream>
#include<malloc.h>
#include<iomanip>
#include<vector>
using namespace std;
//1、建图(邻接矩阵) 2、存储节点的信息(一位数组)3、dijkstra算法 4 怎么样更新最短路径的条数和其累加的增援数目呢

#define maxsize 505//定义的是最多的城市的数目
#define dist_max 1000//初始话距离
#define parent_init -1
typedef int weighttype;//权重代表的是城市之间的道路的距离
typedef int vertex;//顶点数 
int G[maxsize][maxsize];//用简单的邻接矩阵来表示图关系 
bool collected[maxsize];//是否已经被询问
int dist[maxsize];//每个点相对于起源点的距离,可以不断更新 
int Nv, Ne;//图所对应的顶点数和边数
int parent[maxsize];
int flag_road[maxsize];
int team[maxsize];//原本的城市里面存储的队伍数量
int sum_team[maxsize];//从起源城市到当前城市的最短路径中相对来说的队伍召集的最大数量
vertex s;//起点城市
vertex d;//终点城市

//对所用到的数组等参数进行初始化 
void init(int Nv)
{
	for (int i = 0; i < Nv; i++)
	{
		collected[i] = false;
		dist[i] = dist_max;
		parent[i] = parent_init;
		flag_road[i] = 0;
		for (int j = 0; j < Nv; j++)
		{
			G[i][j] = 0;
		}
	}
}

//建图 
void create()
{
	int v1, v2;
	weighttype weight;//代表的是城市之间的距离 
	cin >>Nv>>Ne>>s>>d;
	init(Nv);
	for (int i = 0; i < Nv; i++)
	{
		cin >> team[i];
	}
	for (int i = 0; i < Ne; i++)
	{
		cin >> v1 >> v2>>weight;
		G[v1][v2] = weight;
		G[v2][v1] = weight;
	}
}

vertex find_min(int Nv)
{
	int min = -1;
	int xp = dist_max + 5;
	for (int i = 0; i < Nv; i++)
	{
		if (dist[i] < xp && i != s && !collected[i])
		{
			min = i;
			xp = dist[i];
		}
	}
	return min;
}

void dijkstra(vertex s)
{
	dist[s] = 0;
	collected[s] = true;
	flag_road[s] = 1;
	sum_team[s] = team[s];
	for (int i = 0; i < Nv; i++)
	{
		if (G[s][i] && !collected[i])
		{
			dist[i] = G[s][i];
			parent[i] = s;
			flag_road[i] = 1;
			sum_team[i] = sum_team[s] + team[i];
		}
	}
	while (true)
	{
		vertex tmp = find_min(Nv);
		if (tmp == -1)
		{
			break;
		}
		collected[tmp] = true;
		for (int i = 0; i < Nv; i++)
		{
			if (G[tmp][i] && !collected[i])
			{
				if (dist[i] > dist[tmp] + G[tmp][i])
				{
					dist[i] = dist[tmp] + G[tmp][i];
					parent[i] = tmp;
					flag_road[i] = flag_road[tmp];
					sum_team[i] = team[i] + sum_team[tmp];
				}
				else if (dist[i] == dist[tmp] + G[tmp][i])
				{
					flag_road[i] += flag_road[tmp];
					if (sum_team[i] < team[i] + sum_team[tmp])
					{
						sum_team[i] = team[i] + sum_team[tmp];
					}
				}
			}
		}
	}
}

void print()
{
	cout << flag_road[d] << " " << sum_team[d];
}

int main()
{
	create();
	dijkstra(s);
	print();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值