762 – We Ship Cheap UVA Solution

This is an easy problem from uva judge http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=703

Graphs, Breadth First Search, Single source shortest path(SSSP).

How I did it

  • Read the number of cities that has an edge.
  • Read the origen and destination city.
  • Set the graph.
  • If origen and destination are present in the graph call bfs. Otherwise print No route.
  • If distance of destination is -1(No reachable from origen) cal find path.
  • Print the path.

Hints

  • I got 4 runtime errors. The origen and destination cities are not necessarily in the graph

Input

3
JV PT
KA PT
KA HP
JV HP

2
JV PT
KA HP
JV HP

0
AA BB

1
AA BB
CC BB

1
AA BB
GG PP

2
AA BB
BB CC
GG GG

4
AB JK
PO LK
QW PO
LK AB
AB PO

Output

JV PT
PT KA
KA HP

No route

No route

No route

No route

AB LK
LK PO

Code

#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
#include <set>

using namespace std;

map <int, vector <int> > graph;
map<int,bool> discovered;//keeps track if a node has been reached
map<int,int>  parent;//stores the nodes ancestor that discovered it for the first time
map<int,int>  distances;//stores the distance to reach each node from the source
//For read the data
vector<pair<string,string> > edgesVec;
set<string> mySet;
map<string,int> vec;
vector<string> output;
vector<int> outputId;

void readEdges(int edges)
{
    string c1, c2;
    for(int x=1; x<=edges; x++)
    {
        cin>>c1>>c2;
        pair<string,string> p = make_pair(c1,c2);
        edgesVec.push_back(p);
        mySet.insert(c1);mySet.insert(c2);
    }
}

void setId()
{
    int index = 0;
    for(set<string>::iterator it=mySet.begin(); it!=mySet.end(); it++, index++)
        vec[*it] = index;
}

void read_graph()
{
    //graph.clear();
    int i, vertex1, vertex2;
    string el1, el2;
    for(i = 0; i < edgesVec.size(); i++)
    {
        el1 = edgesVec[i].first;
        el2 = edgesVec[i].second;
        vertex1 = vec[el1];
        vertex2 = vec[el2];

        graph[vertex1].push_back(vertex2);
        graph[vertex2].push_back(vertex1);

        discovered[vertex1] = false;discovered[vertex2] = false;
        parent[vertex1] = -1;parent[vertex2] = -1;
        distances[vertex1] = -1;distances[vertex2] = -1;
    }
}

void clearGraph()
{
    graph.clear();
    discovered.clear();//keeps track if a node has been reached
    parent.clear();//stores the nodes ancestor that discovered it for the first time
    distances.clear();//stores the distance to reach each node from the sour
    edgesVec.clear();
    mySet.clear();
    vec.clear();
    output.clear();
    outputId.clear();
}

void bfs(int start)
{
    int current;//current node being processed
    int next;//reached node by current
    unsigned int i;
    queue<int> vertices;//vertices to process
    distances[start] = 0;
    discovered[start] = true;
    vertices.push(start);
    while(!vertices.empty())
    {
        current = vertices.front();
        vertices.pop();
        for(i = 0; i < graph[current].size(); i++)//for each node connected to current
        {
            next = graph[current][i];
            if(!discovered[next])//if it hasn't been reached
            {
                discovered[next] = true;//mark it as reached
                parent[next] = current;//store its parent
                distances[next] = distances[current]+1;//save the distance
                vertices.push(next);//push it to the queue for further analysis
            }
        }
    }
}

void find_path(int vertex)//recursive procedure to find the path
{
    if(vertex == -1)
        return;
    find_path(parent[vertex]);
    for(map<string,int>::iterator it=vec.begin(); it!=vec.end(); it++)
    {
        if(it->second == vertex)
        {
            output.push_back(it->first);
            break;
        }
    }
    //printf("%d ", vertex);
}

int main()
{
    int edges, flag = 0;
    string c1,c2;
    int origen, destino;
    while(scanf("%d", &edges) != EOF)
    {
        readEdges(edges);
        setId();
        read_graph();
        cin>>c1>>c2;

        if(!flag)
           flag = 1;
        else
            printf("*\n");

        map<string,int>::iterator iter1, iter2;
        iter1 = vec.find(c1);
        iter2 = vec.find(c2);

        if(iter1 == vec.end() || iter2 == vec.end())
           printf("No route\n");
        else
        {
            origen  = vec[c1];
            destino = vec[c2];
            bfs(origen);
            if(distances[destino] == -1)
               printf("No route\n");
            else
            {
                find_path(destino);                for(int x=0; x<output.size(); x++)
                {
                    if(x == 0)
                       cout<<output[x]<<" ";
                    else if(x == output.size()-1)
                        cout<<output[x]<<endl;
                    else
                        cout<<output[x]<<endl<<output[x]<<" ";
                }
            }
        }
        clearGraph();
    }
return 0;
}

Leave a comment