Pagini recente » Cod sursa (job #205910) | Cod sursa (job #2022632) | Cod sursa (job #1335737) | Cod sursa (job #698418) | Cod sursa (job #2823508)
#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;
}