Cod sursa(job #2823508)

Utilizator LordNecrateBiowCuciureanu Dragos-Adrian LordNecrateBiow Data 28 decembrie 2021 18:34:46
Problema Distante Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.35 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>

using namespace std;

ifstream fin("distante.in");
ofstream fout("distante.out");


class Graph
{
public:
	struct Edge
	{
		int _destinationNode, _distance;

		Edge(int destinationNode, int distance = 0) : _destinationNode(destinationNode), _distance(distance) {}
		operator int()
		{
			return _distance;
		}
	};

private:
	bool _oriented;
	bool _weighted;

	int _nrNodes;
	int _nrEdges;

	vector <int> _nodes;
	vector < vector <Edge> > _neighborList;
	
	//does dijkstra's algorithm
	void Dijkstra(priority_queue < pair<int, int>, vector< pair<int, int> >, greater <pair<int, int>> >& heap, vector<bool>& visitedNodes, vector<int>& distances);

public:
	Graph(int nrNodes = 0, int nrEdges = 0, bool oriented = false, bool weighted = false);
	~Graph() {}

	void buildNeighborList(istream& input);

	vector<int> minimalWeightedDistances(int startNode);
};

Graph::Graph(int nrNodes, int nrEdges, bool oriented, bool weighted)
{
	_nrNodes = nrNodes;
	_nrEdges = nrEdges;

	_oriented = oriented;
	_weighted = weighted;

	vector <Edge> emptyVector;

	_neighborList.clear();

	for (int i = 0; i < nrNodes; i++)
	{
		_neighborList.push_back(emptyVector);
	}
}

void Graph::Dijkstra(priority_queue < pair<int, int>, vector< pair<int, int> >, greater <pair<int, int>>>& heap, vector<bool>& visitedNodes, vector<int>& distances)
{
	while (heap.empty() == false)																									//while the heap has elements
	{
		pair <int, int> currentPair = heap.top();
		heap.pop();

		int currentNode = currentPair.second;
		int currentDistance = currentPair.first;

		visitedNodes[currentNode] = true;

		if (currentDistance == distances[currentNode])																				//if the current distance is not the same as the one we have in the distance vector it means that we have 
		{																															//already found a better way
			for (auto& neighborPair : _neighborList[currentNode])																	//visit all neibors
			{
				int neighborNode = neighborPair._destinationNode;
				int edgeDistance = neighborPair._distance;

				if (visitedNodes[neighborNode] == false)																			//if the node has been visited we already know the minimal distance to it
				{
					if (distances[neighborNode] > currentDistance + edgeDistance)													//test if we can find a smaller distance
					{
						distances[neighborNode] = currentDistance + edgeDistance;													//update the minimal distance if we've found a new one
						heap.push(make_pair(distances[neighborNode], neighborNode));												//push the node and it's distance in the heap
					}
				}
			}
		}
	}
}

void Graph::buildNeighborList(istream& input)
{
	int node1, node2, distance;

	for (int i = 0; i < _nrEdges; i++)
	{
		
		input >> node1 >> node2;

		node1--;
		node2--;

		if (_weighted == true)
		{
			fin >> distance;
		}
		else
		{
			distance = 0;
		}

		Edge newEdge(node2, distance);
		_neighborList[node1].push_back(newEdge);

		if (_oriented == false)
		{
			Edge newEdge(node1, distance);
			_neighborList[node2].push_back(newEdge);
		}
	}
}

vector<int> Graph::minimalWeightedDistances(int startNode)
{
	priority_queue < pair<int, int>, vector< pair<int, int> >, greater<pair<int, int>> > heap;

	vector <bool> visited(_nrNodes, false);
	vector <int> distances(_nrNodes, 2e9);

	distances[startNode] = 0;

	heap.push(make_pair(0, startNode));

	Dijkstra(heap, visited, distances);

	return distances;
}




int main()
{
	int nrNodes, nrEdges, nrCases, startNode;
	vector <int> distances;

	fin >> nrCases;

	for (int i = 0; i < nrCases; i++)
	{
		fin >> nrNodes >> nrEdges >> startNode;
		
		vector <int> distancesBronzarel(nrNodes);
		for (int j = 0; j < nrNodes; j++)
		{
			fin >> distancesBronzarel[j];
		}

		Graph graph(nrNodes, nrEdges, false, true);
		graph.buildNeighborList(fin);
		
		startNode--;
		distances = graph.minimalWeightedDistances(startNode);

		bool ok = true;
		for (int j = 0; j < nrNodes; j++)
		{
			if (distances[j] != distancesBronzarel[j])
			{
				ok = false;
			}
		}

		if (ok == true)
		{
			fout << "DA\n";
		}
		else
		{
			fout << "NU\n";
		}
	}

	

	fin.close();
	fout.close();

	return 0;
}