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; }