#include<iostream>
using namespace std;
#define LEN 50
typedef struct stations{
char name[20];
int len;
int roads[50];
struct stations *left ;
struct stations *right ;
}Stations;
typedef struct etree{
int value;
int roadNum;
struct etree *father;
int childnum;
}ETree;
typedef struct queue{
ETree *tie;
struct queue *next;
}Queue;
void pushQueue(Queue &head , ETree *&etree){
Queue *p = head.next , *q = &head ;
while( p!=NULL && (p->tie->value < etree->value) ){
q = p ;
p = p->next ;
}
q->next = (Queue*)malloc(sizeof(Queue)) ;
q->next->tie = etree ;
q->next->next = p ;
}
void freeEtree(ETree *q){
ETree *p;
while(q->childnum==0){
p = q;
q = q->father;
free(p);
if(q!=NULL)
q->childnum--;
else
break;
}
}
void freeAll(Stations * &head){
if(head!=NULL){
freeAll(head->left);
freeAll(head->right);
free(head);
}
}
void showBest(ETree *h,int price[][LEN],char roadName[][20],int roadNum){
if(h!=NULL){
if(h->father==NULL){
printf("%s",roadName[h->roadNum]);
}
else{
int j;
j = h->roadNum ;
if( h->value == ( price[j][j] + h->father->value ) ){
showBest(h->father,price,roadName,roadNum);
if(price[j][roadNum]){
printf("-(%s,%s)",roadName[j],roadName[price[j][roadNum]-1]);
}
else
printf("-%s",roadName[j]);
}
else{
showBest(h->father->father,price,roadName,roadNum);
printf("-(%s,%s)",roadName[h->father->roadNum],roadName[j]);
}
}
}
}
inline int compares(char s1[],int n1 , char s2[] ,int n2){
if(n1!=n2)
return n1-n2;
return strcmp(s1,s2);
}
bool findStation(Stations* &head , Stations* &p , char s[]){
int len = strlen(s);
int t;
Stations *q;
p=head;
while(p!=NULL){
q = p;
t=compares(s,len,p->name,p->len);
if(t<0)
p=p->left;
else
if(t>0)
p=p->right;
else
return true;
}
p = q;
return false;
}
void insert(Stations* &head,char s[] , int road,int price[][LEN]){
Stations *p,*q;
int t;
t=strlen(s);
if(s[t-1]=='\n')
s[t-1] = '\0';
if(head==NULL){
p = (Stations *)malloc(sizeof(Stations));
p->left = NULL;
p->right = NULL;
strcpy( p->name , s );
p->len = strlen(s);
p->roads[0] = 1;
p->roads[1] = road;
head = p;
}
else{
if( findStation(head,p,s) ){
p->roads[0]++;
t=p->roads[0];
p->roads[t] = road ;
for(t--; t >0 ; t--){
price[p->roads[t]][road] = -1;
price[road][p->roads[t]] = -1;
}
}
else{
q = p ;
p = (Stations *)malloc(sizeof(Stations));
p->left = NULL;
p->right = NULL;
strcpy( p->name , s );
p->len = strlen(s);
p->roads[0] = 1;
p->roads[1] = road;
t = compares(s,p->len,q->name,q->len);
if(t<0)
q->left = p;
else
q->right = p;
}
}
}
int GetRoadNum(char *r,char roadName[][20],int roadNum){
for(int i=0 ; i<roadNum ; i++)
if(strcmp(roadName[i],r)==0)
return i;
return 0;
}
void main()
{
//[roadnum][roadnum+1]
int price[LEN][LEN]={0};
char roadName[LEN][20];
int i,j,k,t;
char line[20];
int roadNum;
Stations *head=NULL;
FILE *fp;
if((fp=fopen("stations.txt","r"))==NULL){
printf("找不到stations文件\n");
return;
}
roadNum = 0 ;
while(!feof(fp)){
fscanf(fp,"%s%*c",roadName[roadNum]);
fgets(line,19,fp);
while( !feof(fp) && line[0]!='\n'){
insert(head,line,roadNum,price);
fgets(line,19,fp);
}
roadNum++;
}
insert(head,line,roadNum-1,price);
fclose(fp);
if((fp=fopen("price.txt","r"))==NULL){
printf("找不到price文件");
}
while(!feof(fp)){
fscanf(fp,"%s",line);
fscanf(fp,"%d",&k);
for(t=0; line[t]!='\0' && line[t]!= ',' ; t++ );
if(line[t]==','){
line[t] = '\0' ;
i = GetRoadNum(line,roadName,roadNum);
j = GetRoadNum(line+t+1,roadName,roadNum);
price[i][j] = k;
price[j][i] = k;
if(price[i][i] > k ){
price[i][i] = k;
price[i][roadNum]=j+1;
}
if(price[j][j] > k ){
price[j][j] = k;
price[j][roadNum]=i+1;
}
}
else{
i = GetRoadNum(line,roadName,roadNum);
price[i][i] = k;
}
}
fclose(fp);
char starts[20]={"五棵松"},ends[20]={"奥体中心"};
Stations* sroad,*eroad;
Queue Qhead, *h;
ETree *p,*q;
while(true){
char Flag[LEN]={0}; // 为-1表示目标 为0表示尚未发生过扩展
Qhead.next = NULL;
Qhead.tie = NULL;
scanf("%[^,\n]s",starts);
if(getchar()!=',')
break;
scanf("%[^\n]s",ends);
getchar();
if(!findStation(head,sroad,starts)){
printf("未找到%s的匹配项\n",starts);
continue;
}
if(!findStation(head,eroad,ends)){
printf("未找到%s的匹配项\n",ends);
continue;
}
for( i = 1 ; i <= sroad->roads[0] ; i++ ){
p = (ETree*)malloc(sizeof(ETree));
p->father = NULL ;
p->childnum = 0 ;
p->roadNum = sroad->roads[i];
p->value = price[p->roadNum][p->roadNum] ;
pushQueue(Qhead,p);
}
for( i = 1 ; i <= eroad->roads[0] ; i++ ){
Flag[eroad->roads[i]] = -1 ;
}
while( Qhead.next != NULL ){
h =Qhead.next;
q = h->tie ;
if(Flag[q->roadNum]==-1){
break;
}
Qhead.next = Qhead.next->next;
i = q->roadNum;
if(Flag[i]!=1){
for(j=0 ; j<roadNum ; j++ ){
if(price[i][j]){
q->childnum++;
p = (ETree*)malloc(sizeof(ETree));
p->father = q ;
p->childnum = 0 ;
p->roadNum = j ;
k = price[j][j] + q->value ;
if(price[i][j]>0 ){
if(q->father!=NULL)
t = price[i][j] + q->father->value ;
else
t = price[i][j] ;
if(k>t)
k = t;
}
p->value = k ;
pushQueue(Qhead,p);
}
}
Flag[i] = 1;
}
freeEtree(h->tie);
free(h);
}
if(Qhead.next!=NULL){
showBest(q,price,roadName,roadNum);
printf(" = %d\n",q->value);
}
else
printf("此路不通\n");
for( ; Qhead.next!=NULL ; ){
h = Qhead.next;
Qhead.next = Qhead.next->next;
freeEtree(h->tie);
free(h);
}
}
freeAll(head);
}