RouteFinding

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值