3700. Easy Dijkstra Problem

 

Determine the shortest path between the specified vertices in the graph given in the input data.

·        Hint: You can use Dijkstra's algorithm.

·        Hint 2: if you're a lazy C++ programmer, you can use set and cin/cout (with sync_with_stdio(0)) – it should suffice.

 

Input. First line contains the number of test cases. For each test case the number of vertices v and the number of edges are given. Then k lines follow, each containing the following numbers separated by a single space: ai, bi, ci. It means that the graph being described contains an edge from ai to bi, with a weight of ci. Below the graph description a line containing a pair of integers A, B is present. The goal is to find the shortest path from vertex A to vertex B. All numbers in the input data are integers in the range 0..10000.

 

Output. For each test case your program should output (in a separate line) the length of the shortest path from vertex A to vertex B. In case there is no such path, your program should output a single word "NO" (without quotes).

 

Sample input

Sample output

3

3 2

1 2 5

2 3 7

1 3

3 3

1 2 4

1 3 7

2 3 1

1 3

3 1

1 2 4

1 3

12

5

NO

 

 

ÐÅØÅÍÈÅ

àëãîðèòì Äåéêñòðû

 

Àíàëèç àëãîðèòìà

 çàäà÷å ñëåäóåò ðåàëèçîâàòü àëãîðèòì Äåéêñòðû. Ïîñêîëüêó êîëè÷åñòâî âåðøèí è ðåáåð â ãðàôå äî 10000, òî ãðàô ñëåäóåò õðàíèòü â âèäå ñïèñêà ñìåæíîñòè. Ãðàô ÿâëÿåòñÿ îðèåíòèðîâàííûì.

 

Ðåàëèçàöèÿ àëãîðèòìà

 

#include <cstdio>

#include <cstring>

#include <vector>

#define MAX 10010

#define INF 2100000000

using namespace std;

 

int i, j, MinDist, n, Edges, source, dest;

int b, e, dist, w, tests;

 

struct road

{

  int v, dist;

  road(int vv, int dd) {v = vv; dist = dd;}

};

vector<vector<road> > m;

int used[MAX], d[MAX];

 

int main(void)

{

  scanf("%d",&tests);

  while(tests--)

  {

    scanf("%d %d",&n,&Edges);

    m.assign(n+1,vector<road>());

    memset(used,0,sizeof(used));

 

    for(i = 0; i < Edges; i++)

    {

      scanf("%d %d %d",&b,&e,&dist);

      m[b].push_back(road(e,dist));

    }

 

    scanf("%d %d",&source,&dest);

    memset(d,0x3F,sizeof(d)); d[source] = 0;

 

    for(i = 1; i < n; i++)

    {

      MinDist = INF / 2;

      for(j = 1; j <= n; j++)

        if (!used[j] && d[j] < MinDist) {MinDist = d[j]; w = j;}

      for(j = 0; j < m[w].size(); j++)

      {

        road to = m[w][j];

        if (!used[to.v]) d[to.v] = min(d[to.v], d[w] + to.dist);

      }

      used[w] = 1;

    }

 

    if (d[dest] == 0x3F3F3F3F) printf("NO\n");

    else printf("%d\n",d[dest]);

  }

  return 0;

}

 

Ðåàëèçàöèÿ àëãîðèòìà - êëàññû

 

#include <cstdio>

#include <vector>

#include <queue>

#define INF 0x3F3F3F3F

using namespace std;

 

class Edge

{

public:

  int To, Len;

  Edge(int To, int Len = 1) : To(To), Len(Len) {}

};

 

class Prior

{

public:

  int Dist, Vertex;

  Prior(int Dist, int Vertex) : Dist(Dist), Vertex(Vertex) {}

  int operator< (const Prior &a) const

  {  

    return Dist < a.Dist;

  }

  int operator> (const Prior &a) const

  {  

    return Dist > a.Dist;

  }

};

 

class Graph

{

public:

  static const int INF2 = 0x3F3F3F3F;

  int n;

  vector<vector<Edge> > g;

  Graph(int n = 1) : n(n)

  {

    g = vector<vector<Edge> >(n);

  }

 

  void AddEdge(int From, int To, int Len)

  {

    g[From].push_back(Edge(To,Len));

  }

 

  void Dijkstra(int Source, vector<int> &dist)

  {

     priority_queue<Prior, vector<Prior>, greater<Prior> > pq;

     //(distance,node)

     pq.push(Prior(0,Source)); dist[Source] = 0;

 

    while(!pq.empty())

    {

      int v = pq.top().Vertex;

      int d = pq.top().Dist; pq.pop();

      if (d > dist[v]) continue;

      for(int i = 0; i < g[v].size(); i++)

      {

        int to = g[v][i].To ; // v -> to

        int Len = g[v][i].Len;

        if (dist[to] > dist[v] + Len)

        {

          dist[to] = dist[v] + Len;

          pq.push(Prior(dist[to],to));

        }

      }

    }

  }

};

 

int i, n, tests, From, To, Len;

int Source, Dest, Edges;

Graph *g;

vector<int> dist;

 

int main(void)

{

  scanf("%d",&tests);

  while(tests--)

  {

    scanf("%d %d",&n,&Edges);

    g = new Graph(n+1);

    dist = vector<int>(n+1,INF);

 

    for(i = 0; i < Edges; i++)

    {

      scanf("%d %d %d",&From,&To,&Len);

      g->AddEdge(From,To,Len);

    }

 

    scanf("%d %d",&Source,&Dest);

    g->Dijkstra(Source,dist);

 

    if (dist[Dest] == INF) printf("NO\n");

    else printf("%d\n",dist[Dest]);

  }

  return 0;

}