#include<cstdio>
#include<map>
#include<vector>
#include<string>
using namespace std;
map<int, int> vmap;
map<int, vector<int> > setMap;
vector<int> pathName;
struct Station{
int id;
char routeID;
char name;
}station[1000];
int dist[1000][1000], value[1000];
int visited[1000], path[1000];
char route[3000];
int pre[1000], rank[1000];
void makeset(int x){
pre[x] = -1;
rank[x] = 0;
vector<int> v;
v.push_back(x);
setMap[x] = v;
}
int find(int x) {
int r = x;
while(pre[r] != -1)
r = pre[r];
while(x != r){
int q = pre[x];
pre[x] = r;
x = q;
}
return r;
}
void unionone(int a, int b){
int t1 = find(a);
int t2 = find(b);
if(rank[t1] > rank[t2]){
pre[t2] = t1;
for(vector<int>::iterator it = setMap[t2].begin(); it != setMap[t2].end(); it++)
setMap[t1].push_back(*it);
setMap[t2].clear();
}
else if(rank[t1] > rank[t2]){
pre[t1] = t2;
for(vector<int>::iterator it = setMap[t1].begin(); it != setMap[t1].end(); it++)
setMap[t2].push_back(*it);
setMap[t1].clear();
}
else{
pre[t1] = t2;
for(vector<int>::iterator it = setMap[t1].begin(); it != setMap[t1].end(); it++)
setMap[t2].push_back(*it);
setMap[t1].clear();
rank[t2]++;
}
}
int main(){
int n;
scanf("%d", &n);
int index = 0;
memset(dist, 0, sizeof(dist));
for(int i = 0; i < 1000; i++)
for(int j = i + 1; j < 1000; j++)
dist[i][j] = dist[j][i] = 9999;
while(n--){
scanf("%s", &route);
char routeID = route[0];
for(int i = 2; i < strlen(route); ){
if(route[i] >= 'a' && route[i] <= 'z'){
if(vmap.find(routeID << 10 + route[i]) == vmap.end()){
vmap[routeID << 10 + route[i]] = index;
station[index].id = index;
station[index].routeID = routeID;
station[index].name = route[i];
index++;
}
if(i > 2){
dist[vmap[routeID << 10 + route[i-1]]][vmap[routeID << 10 + route[i]]] = dist[vmap[routeID << 10 + route[i]]][vmap[routeID << 10 + route[i-1]]] = 1;
}
i++;
}else if(route[i] == '='){
char start = route[i-1];
if(setMap.find(vmap[routeID << 10 + start]) == setMap.end())
makeset(vmap[routeID << 10 + start]);
while(route[i] == '='){
char nextRouteID = route[i+1];
char nextStationID = route[i+2];
if(vmap.find(nextRouteID << 10 + nextStationID) == vmap.end()){
vmap[nextRouteID << 10 + nextStationID] = index;
station[index].id = index;
station[index].routeID = nextRouteID;
station[index].name = nextStationID;
index++;
}
if(setMap.find(vmap[nextRouteID << 10 + nextStationID]) == setMap.end())
makeset(vmap[nextRouteID << 10 + nextStationID]);
if(find(vmap[routeID << 10 + start]) != find(vmap[nextRouteID << 10 + nextStationID]))
unionone(vmap[routeID << 10 + start], vmap[nextRouteID << 10 + nextStationID]);
i += 3;
}
if(i < strlen(route)){
char end = route[i];
if(vmap.find(routeID << 10 + end) == vmap.end()){
vmap[routeID << 10 + end] = index;
station[index].id = index;
station[index].routeID = routeID;
station[index].name = end;
index++;
}
dist[vmap[routeID << 10 + start]][vmap[routeID << 10 + end]] =
dist[vmap[routeID << 10 + end]][vmap[routeID << 10 + start]] = 1;
i++;
}
} // end for else
} // end for i
}//end while n
for(map<int, vector<int> >::iterator it = setMap.begin(); it != setMap.end(); it++){
vector<int> vec = it->second;
for(int i = 0; i < vec.size(); i++)
for(int j = i + 1; j < vec.size(); j++){
dist[vec[i]][vec[j]] = dist[vec[j]][vec[i]] = 3;
}
}
/**
for(int i = 0; i < index; i++){
for(int j = 0; j < index; j++){
printf("%d\t", dist[i][j]);
}
printf("\n");
}
**/
while(scanf("%s", &route) != EOF){
if(strcmp(route,"#") == 0)break;
int source = vmap[route[0] << 10 + route[1]];
int destion = vmap[route[2] << 10 + route[3]];
if(source == destion){
printf("%3d: %c%c%c", 0, station[source].routeID, station[source].name, station[source].name);
continue;
}
pathName.clear();
for(int i = 0; i < index; i++){
value[i] = dist[source][i];
path[i] = source;
visited[i] = 0;
}
visited[source] = 1;
path[source] = -1;
int mindist;
for(int i = 0; i < index; i++){
mindist = 9999;
int u;
for(int j = 0; j < index; j++){
if(!visited[j] && value[j] < mindist){
mindist = value[j];
u = j;
}
}
visited[u] = 1;
for(int j = 0; j < index; j++){
if(!visited[j] && mindist + dist[u][j] < value[j]){
value[j] = mindist + dist[u][j];
path[j] = u;
}
}
} // end for index
printf("%3d: ", value[destion]);
pathName.push_back(station[destion].name);
pathName.push_back(station[destion].routeID);
for(int i = path[destion]; i != -1; i = path[i]){
pathName.push_back(station[i].name);
pathName.push_back(station[i].routeID);
}
/*
for(int i = 0; i < pathName.size(); i++) {
printf("%c", pathName[i]);
}
*/
printf("\n");
int parent = -1;
for(int i = pathName.size() - 1; i > 0; i = i - 2){
if(parent == -1) {
printf("%c", pathName[i]);
printf("%c", pathName[i-1]);
parent = pathName[i];
}else if(pathName[i] == parent) {
printf("%c", pathName[i-1]);
}else {
printf("=");
printf("%c", pathName[i]);
printf("%c", pathName[i-1]);
parent = pathName[i];
}
}
printf("\n");
}
return 0;
}
#include<map>
#include<vector>
#include<string>
using namespace std;
map<int, int> vmap;
map<int, vector<int> > setMap;
vector<int> pathName;
struct Station{
int id;
char routeID;
char name;
}station[1000];
int dist[1000][1000], value[1000];
int visited[1000], path[1000];
char route[3000];
int pre[1000], rank[1000];
void makeset(int x){
pre[x] = -1;
rank[x] = 0;
vector<int> v;
v.push_back(x);
setMap[x] = v;
}
int find(int x) {
int r = x;
while(pre[r] != -1)
r = pre[r];
while(x != r){
int q = pre[x];
pre[x] = r;
x = q;
}
return r;
}
void unionone(int a, int b){
int t1 = find(a);
int t2 = find(b);
if(rank[t1] > rank[t2]){
pre[t2] = t1;
for(vector<int>::iterator it = setMap[t2].begin(); it != setMap[t2].end(); it++)
setMap[t1].push_back(*it);
setMap[t2].clear();
}
else if(rank[t1] > rank[t2]){
pre[t1] = t2;
for(vector<int>::iterator it = setMap[t1].begin(); it != setMap[t1].end(); it++)
setMap[t2].push_back(*it);
setMap[t1].clear();
}
else{
pre[t1] = t2;
for(vector<int>::iterator it = setMap[t1].begin(); it != setMap[t1].end(); it++)
setMap[t2].push_back(*it);
setMap[t1].clear();
rank[t2]++;
}
}
int main(){
int n;
scanf("%d", &n);
int index = 0;
memset(dist, 0, sizeof(dist));
for(int i = 0; i < 1000; i++)
for(int j = i + 1; j < 1000; j++)
dist[i][j] = dist[j][i] = 9999;
while(n--){
scanf("%s", &route);
char routeID = route[0];
for(int i = 2; i < strlen(route); ){
if(route[i] >= 'a' && route[i] <= 'z'){
if(vmap.find(routeID << 10 + route[i]) == vmap.end()){
vmap[routeID << 10 + route[i]] = index;
station[index].id = index;
station[index].routeID = routeID;
station[index].name = route[i];
index++;
}
if(i > 2){
dist[vmap[routeID << 10 + route[i-1]]][vmap[routeID << 10 + route[i]]] = dist[vmap[routeID << 10 + route[i]]][vmap[routeID << 10 + route[i-1]]] = 1;
}
i++;
}else if(route[i] == '='){
char start = route[i-1];
if(setMap.find(vmap[routeID << 10 + start]) == setMap.end())
makeset(vmap[routeID << 10 + start]);
while(route[i] == '='){
char nextRouteID = route[i+1];
char nextStationID = route[i+2];
if(vmap.find(nextRouteID << 10 + nextStationID) == vmap.end()){
vmap[nextRouteID << 10 + nextStationID] = index;
station[index].id = index;
station[index].routeID = nextRouteID;
station[index].name = nextStationID;
index++;
}
if(setMap.find(vmap[nextRouteID << 10 + nextStationID]) == setMap.end())
makeset(vmap[nextRouteID << 10 + nextStationID]);
if(find(vmap[routeID << 10 + start]) != find(vmap[nextRouteID << 10 + nextStationID]))
unionone(vmap[routeID << 10 + start], vmap[nextRouteID << 10 + nextStationID]);
i += 3;
}
if(i < strlen(route)){
char end = route[i];
if(vmap.find(routeID << 10 + end) == vmap.end()){
vmap[routeID << 10 + end] = index;
station[index].id = index;
station[index].routeID = routeID;
station[index].name = end;
index++;
}
dist[vmap[routeID << 10 + start]][vmap[routeID << 10 + end]] =
dist[vmap[routeID << 10 + end]][vmap[routeID << 10 + start]] = 1;
i++;
}
} // end for else
} // end for i
}//end while n
for(map<int, vector<int> >::iterator it = setMap.begin(); it != setMap.end(); it++){
vector<int> vec = it->second;
for(int i = 0; i < vec.size(); i++)
for(int j = i + 1; j < vec.size(); j++){
dist[vec[i]][vec[j]] = dist[vec[j]][vec[i]] = 3;
}
}
/**
for(int i = 0; i < index; i++){
for(int j = 0; j < index; j++){
printf("%d\t", dist[i][j]);
}
printf("\n");
}
**/
while(scanf("%s", &route) != EOF){
if(strcmp(route,"#") == 0)break;
int source = vmap[route[0] << 10 + route[1]];
int destion = vmap[route[2] << 10 + route[3]];
if(source == destion){
printf("%3d: %c%c%c", 0, station[source].routeID, station[source].name, station[source].name);
continue;
}
pathName.clear();
for(int i = 0; i < index; i++){
value[i] = dist[source][i];
path[i] = source;
visited[i] = 0;
}
visited[source] = 1;
path[source] = -1;
int mindist;
for(int i = 0; i < index; i++){
mindist = 9999;
int u;
for(int j = 0; j < index; j++){
if(!visited[j] && value[j] < mindist){
mindist = value[j];
u = j;
}
}
visited[u] = 1;
for(int j = 0; j < index; j++){
if(!visited[j] && mindist + dist[u][j] < value[j]){
value[j] = mindist + dist[u][j];
path[j] = u;
}
}
} // end for index
printf("%3d: ", value[destion]);
pathName.push_back(station[destion].name);
pathName.push_back(station[destion].routeID);
for(int i = path[destion]; i != -1; i = path[i]){
pathName.push_back(station[i].name);
pathName.push_back(station[i].routeID);
}
/*
for(int i = 0; i < pathName.size(); i++) {
printf("%c", pathName[i]);
}
*/
printf("\n");
int parent = -1;
for(int i = pathName.size() - 1; i > 0; i = i - 2){
if(parent == -1) {
printf("%c", pathName[i]);
printf("%c", pathName[i-1]);
parent = pathName[i];
}else if(pathName[i] == parent) {
printf("%c", pathName[i-1]);
}else {
printf("=");
printf("%c", pathName[i]);
printf("%c", pathName[i-1]);
parent = pathName[i];
}
}
printf("\n");
}
return 0;
}