sicily 1132. ROUTES

1132. ROUTES

Constraints

Time Limit: 10 secs, Memory Limit: 32 MB

Description

The Truckee Freight Company has a network consisting of a number of terminal stations and transfer stations.

¨         At the terminal stations, the company deals with its customers, i.e., they accept cargo from senders and deliver cargo to recipients. When a cargo is shipped from a particular terminal station (the "source") to another terminal station (the "destination"), it must pass through one or more transfer stations.

¨         The company's stations are ordered into a tree-like hierarchy.

¨         The main transfer station is at the highest level of the hierarchy (the root of the tree).

¨         Every station (be it a terminal station or a transfer station), except the main transfer station, is connected to exactly one station on the next higher level of the hierarchy, called the parent station. A terminal station is not connected to any other station except for its parent. A transfer station is connected to one or more stations on the next lower level of the hierarchy; its children.

¨         The entire network will have at least two terminal stations.

¨         Every station appears only once in the shipping network, and is labeled by a unique upper case letter.

Consider the example shown in the figure. The main transfer station is T, and its children are B, W, D, and E. The terminal stations are F, H, R, J, K, W, L, and E. The transfer stations are T, B, M, and D.

 

 

Graph representation of the trucking network T(B(FHM(RJK))WD(L)E) 

Given the particular arrangement of routes for the Truckee Freight Company, you are to determine routes for transporting a list of customer packages.

Input

The input file will contain a sequence of routing problems separated by a single blank line. A given routing problem will have the form:

NETWORK

SOURCE_TERMINAL_STATION(1) DEST_TERMINAL_STATION(1)

SOURCE_TERMINAL_STATION(2) DEST_TERMINAL_STATION(2)

SOURCE_TERMINAL_STATION(N) DEST_TERMINAL_STATION(N)

¨         NETWORK is a parenthesized expression version of the routing network. For example, the network in figure 1 would be appear as

T(B(FHM(RJK))WD(L)E)

In this notation, the children of a node are listed in parenthesis after the node itself. A valid grammar for such expressions is

 main-transfer-station ::= transfer-station
transfer-station ::= letter "(" children ")"
terminal-station ::= letter
children ::= child | child children
child ::= transfer-station | terminal-station
letter ::= "A" | "B" | ... | "Z"

Here , the vertical bar means a logical "or" and the quoted items mean those literal symbols.

¨         SOURCE_TERMINAL_STATION(k) and DEST_TERMINAL_STATION(k) are the single uppercase characters representing which distinct terminal stations a customer package starts and where it should end.

Output

Other than the standard leader and trailer, the output file has a line of output for each line of input:

²        The network configuration is echoed to the output file in the same format as the input.

²        For each route in a given sequence of routes, the package path is written on a single line in the form:
STATION(1)->STATION(2)->...->STATION(N)

The route with the fewest number of transfers is always chosen.

Like the input file, multiple routing problems are separated by single blank line.

Sample Input

T(B(FHM(RJK))WD(L)E)
F H
R H
H R
J E
L F

M(AB)
A B
B A

Sample Output

T(B(FHM(RJK))WD(L)E)
F->B->H
R->M->B->H
H->B->M->R
J->M->B->T->E
L->D->T->B->F

M(AB)
A->M->B
B->M->A

题目分析

求从一个火车站到另一个火车站的最短路径
题目保证每个节点只有一个父亲,
只有一个根节点,至少有两个叶子节点
思路类似与电路稳定性那道题
1, 先扫描字符串,获得跨度最小的括号
2, 则括号前的字符为父亲,括号内的为孩子
这样可以确定父亲到所有后代(直接和间接)的最短路径,同时确定后代到父亲的最短路径
3, 假设i,j为父亲的后代,i!=j且i与j为确定最短路径,则dis[i][j] = dis[i][papa] + dis[papa][j]
以此确定每两个后代的最短路径
4, 从原字符串中去掉此括号,保留父亲,如果字符串长度不为1,则重复一步骤
在每轮查询结束后会输入一个空行,不要求任何处理,
每两个案例间打印空行


#include <iostream>

std::string ans[26][26];

std::string reverse(int s, int e) {
  std::string str = "";
  for (int i = ans[s][e].length()-1; i >= 0; --i)
    str += ans[s][e][i];
  return str;
}

std::string connected(std::string s1, std::string s2) {
  std::string s = s1;
  for (int i = 1; i < s2.length(); ++i)
    s += s2[i];
  return s;
}

void deal(std::string str) {
  int root = str[0] - 'A';
  
  for (int i = 2; i <= str.length()-2; ++i) {
    for (int j = 0; j < 26; ++j) {
      if (j != root && ans[str[i]-'A'][j].length() > 0) {
        ans[root][j] = ans[root][root] + ans[str[i]-'A'][j];
        ans[j][root] = reverse(root, j);
      }
    }
  }

  for (int i = 0; i < 26; ++i) {
    if (ans[i][root].length() > 1) {
      for (int j = 0; j < 26; ++j) {
        if (i != j && ans[root][j].length() > 1 && ans[i][j].length() == 0) {
          ans[i][j] = connected(ans[i][root], ans[root][j]);
        }
      }
    }
  }

}

void init(std::string line) {
//std::cout << line << std::endl;
  int minl = 0, minr = line.length()-1;
  int start, end;
  for (int i = 0; i < line.length(); ++i) {
    if (line[i] == '(') {
      start = i;
    } else if (line[i] == ')') {
      end = i;
      if (minr - minl > end - start) {
        minr = end;
        minl = start;
      }
    }
  }

  std::string str = "";
  for (int i = minl-1; i <= minr; ++i)
    str += line[i];
  deal(str);
//std::cout << "====" << str << std::endl;
  if (minl == 1 && minr == line.length()-1)
    return;
  std::string next = "";
//std::cout << "====" << minl << "--" << minr << std::endl;
  for (int i = 0; i < minl; ++i)
    next += line[i];
  for (int i = minr+1; i < line.length(); ++i)
    next += line[i];
//std::cout << "====" << next << std::endl;
  init(next);
}

int main()
{
  std::string line;
  bool first = true;
  while (getline(std::cin, line)) {
    if (!first) std::cout << std::endl;
    first = false;
    for (int i = 0; i < 26; ++i)
      for (int j = 0; j < 26; ++j) {
        ans[i][j] = "";
        if (i == j)
          ans[i][j] += char('A' + i);
      }
    init(line);
    std::cout << line << std::endl;
    while (getline(std::cin, line) && line.length() != 0) {
      std::cout << ans[line[0]-'A'][line[2]-'A'][0];
      for (int i = 1; i < ans[line[0]-'A'][line[2]-'A'].length(); ++i)
        std::cout << "->" << ans[line[0]-'A'][line[2]-'A'][i];
      std::cout << std::endl;
    }
  }
}                                 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值