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;
}