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