Language: C++

#include <vector>
#include <queue>
#include <algorithm>
template <size_t N, typename COST_T, COST_T INF>
class Dijkstra
{
public:
	struct Path
	{
		int connectingIndex;
		COST_T cost;
	};

	struct Agent
	{
		int index;
		COST_T cost;

		bool operator<(const Agent& rhs) const
		{
			return cost > rhs.cost;
		}
	};

	Dijkstra()
	{
		init_paths();
	}

	void init_paths()
	{
		edges.assign(N, std::vector<Path>());
	}

	void add_path(int from, int to, COST_T cost)
	{
		edges[from].push_back(Path{ to, cost });
	}

	void add_path_undirected(int node1, int node2, COST_T cost)
	{
		edges[node1].push_back(Path{ node2, cost });
		edges[node2].push_back(Path{ node1, cost });
	}

	void find_shortest_path(std::vector<int> start_indices)
	{
		// initialize
		que = std::priority_queue<Agent>();
		fill(begin(minimum_cost), end(minimum_cost), INF);

		for (int start_index : start_indices)
		{
			que.push(Agent{ start_index, /*cost*/0 });
		}
		while (!que.empty())
		{
			Agent agent = que.top(); que.pop();
				
			if (minimum_cost[agent.index] <= agent.cost)
			{
				continue;
			}
			minimum_cost[agent.index] = agent.cost;

			for (auto path : edges[agent.index])
			{
				int next_index = path.connectingIndex;
				COST_T next_cost = agent.cost + path.cost;
				if (minimum_cost[next_index] > next_cost)
				{
					que.push(Agent{ next_index,
					                next_cost });
				}
			}
		}
	}

	COST_T get_cost(int index) const
	{
		return minimum_cost[index];
	}

	std::vector<std::vector<Path>> edges;
	std::priority_queue<Agent> que;
	int start;
	int goal;
	COST_T minimum_cost[N];
	int prev_node[N];
};

#include <iostream>
#include <tuple>
using namespace std;

int N, M, K;
const int INF = 1e9;
Dijkstra<3001, int, INF> dijkstra;
vector<tuple<int, int, int>> edges;

int main()
{
	cin >> N >> M >> K;
	for (int i = 0; i < N; ++i)
	{
		int a, b, l;
		cin >> a >> b >> l;
		dijkstra.add_path_undirected(a, b, l);
		edges.emplace_back(a, b, l);
	}

	vector<int> start_indices;
	for (int i = 0; i < K; ++i)
	{
		int s;
		cin >> s;
		start_indices.push_back(s);
	}

	dijkstra.find_shortest_path(start_indices);

	int max_distance = 0;
	for (auto edge : edges)
	{
		int a = std::get<0>(edge);
		int b = std::get<1>(edge);
		int l = std::get<2>(edge);
		int a_distance = dijkstra.get_cost(a);
		int b_distance = dijkstra.get_cost(a);
		int distance = a_distance
			+ (b_distance - a_distance + l) / 2
			+ (b_distance - a_distance + l) % 2;
		max_distance = max(max_distance, distance);
	}
	cout << max_distance << endl;
}

Compiler output:
a.cc: In instantiation of 'void Dijkstra<N, COST_T, INF>::find_shortest_path(std::vector<int>) [with long unsigned int N = 3001; COST_T = int; COST_T INF = 1000000000]':
a.cc:120:29:   required from here
  120 |         dijkstra.find_shortest_path(start_indices);
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
a.cc:50:27: error: 'begin' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
   50 |                 fill(begin(minimum_cost), end(minimum_cost), INF);
      |                      ~~~~~^~~~~~~~~~~~~~
In file included from /usr/include/c++/14/vector:69,
                 from a.cc:1:
/usr/include/c++/14/bits/range_access.h:114:37: note: 'template<class _Tp> const _Tp* std::begin(const valarray<_Tp>&)' declared here, later in the translation unit
  114 |   template<typename _Tp> const _Tp* begin(const valarray<_Tp>&) noexcept;
      |                                     ^~~~~
a.cc:50:46: error: 'end' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
   50 |                 fill(begin(minimum_cost), end(minimum_cost), INF);
      |                                           ~~~^~~~~~~~~~~~~~
/usr/include/c++/14/bits/range_access.h:116:37: note: 'template<class _Tp> const _Tp* std::end(const valarray<_Tp>&)' declared here, later in the translation unit
  116 |   template<typename _Tp> const _Tp* end(const valarray<_Tp>&) noexcept;
      |                                     ^~~
a.cc:50:21: error: 'fill' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation
   50 |                 fill(begin(minimum_cost), end(minimum_cost), INF);
      |                 ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/14/algorithm:86,
                 from a.cc:3:
/usr/include/c++/14/pstl/glue_algorithm_defs.h:191:1: note: 'template<class _ExecutionPolicy, class _ForwardIterator, class _Tp> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> std::fill(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&)' declared here, later in the translation unit
  191 | fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value);
      | ^~~~