问题分析:
1.建立合适的图模型
2.根据不同的优化查询调整dij
dij算法的设计思路:
大体思想:
设S是被探查的结点的集合,U是G中除S外的结点集合,初始时,S={s},d(s) =0,若s到U中的结点u有边,则d(u)=边上的权值或长度(具体自己定义),如果没有边,则d(u)=∞
a.从U中选择一个到s距离最小的顶点v,将v加入到S中,此时的距离d(v)就是s到v的最短路径
b.以v为中间结点,重新考虑s到U中的各个结点的距离;如果通过v到U中的结点u的距离比原来不通过v的更小,则更新这个距离值,否则不更新
c.重复a、b直到所有结点都被包含到S中
那么如何去优化?
主要操作是a,b,所以先对a,b两个步骤进行初始的优化:
a:每次选择最短路径,依次遍历o(n),排序操作基本都是o(nlogn),有没有可以降到o(logn),所以可以选择最小堆minheap
b考虑的是s到U中的各个结点,那么想想其实可能得到更新的都是s的邻接点,所以这里可以遍历邻接点。
数据结构的选择:
图的存储:邻接表(边数不多的情况下)
存储节点以及节点与初始点的距离:最小堆
最优路径np_r [1:n] np_v[1:n] //线路号 站点号
数据定义:
//站点
struct site//站点
{
char name;
T x_position;
T y_position;
}
//线路
struct route//路线
{
int route_num;//线路号
int ticket_price;//票价
int dep_ti_interval;//发车时间间隔
int speed;//车速
int site_num;//站点数
site<T> *sit;//站点数组
route() {}
void rout()
{
sit=new site<T>[site_num+5];
}
};
//站点与发车站的距离
struct po//站点
{//记录站点的距离初始站和终点站的距离
map<int,pair<double,double>>mp;//加快查找速度
}point[100];
//存图链表节点
struct chainNode
{
int sit_num; //顶点号
int route_num;//线路号
double disval;//边距离
double timval;//边时间
int priceval;//边票价
int dep_ti_interval;//发车间隔
bool index;//标志线路的正反
chainNode *next;//下一个节点
};
//将信息转化成图的信息//图类(进行加边、求路径)
//邻接表 数组+链表
//插入操作每次插入firstNode,时间复杂度降到o(1)
class chain
{
public:
chainNode* firstNode;
int listsize;
chain();
~chain();
//存图时插入节点信息
void insert(int v2,int rout_num,double disv,double timv,int priv,int d_i,bool index);
int size() {return listsize; }
};
class linkedGraph
{
protected:
chain *aList; //存图
int np_v[100];//记录前驱节点
int np_r[100];//记录点与边所在的线路号
public:
linkedGraph();
~linkedGraph();
//插入边
void insertEdge(int v1,int v2,int rout_num,double disv,double timv,int priv,int d_i,double d_h1,double d_h2);
//Dijkstra过程
void dij(int s,int _dij,int t);
void print(int t);
}
预处理操作:
预处理数据,进行存图:
1.进行距离的计算,得出disval;
2.进行时间的计算,得出timval;
3.进行线路的正反向判断,并计算正反向的到达时间dep_he;
void init(linkedGraph& li)
{ //<100条线路
cout<<"请输入线路的个数:"<<endl;
int num;cin>>num;route<int>rt[100];
for(int i=1;i<=num;i++)
{
cout<<"请输入第"<<i<<"条线路号:"<<endl;cin>>rt[i].route_num;
cout<<"请输入该条线路站点的个数:"<<endl;cin>>rt[i].site_num;rt[i].rout();
cout<<"请输入站点名称及位置坐标:(站点名称用大写字母表示,从'A'开始命名)"<<endl;
for(int j=0;j<rt[i].site_num;j++)
{
cin>>rt[i].sit[j].name;cin>>rt[i].sit[j].x_position;cin>>rt[i].sit[j].y_position;
}cout<<"请输入发车时间间隔及车速和票价:"<<endl;cin>>rt[i].dep_ti_interval>>rt[i].speed>>rt[i].ticket_price;
double dep_he[100];double ddisval[100];double timval[100];memset(dep_he,0,sizeof(dep_he));memset(ddisval,0,sizeof(ddisval));
memset(timval,0,sizeof(timval));
for(int j=0;j<rt[i].site_num-1;j++)
{
ddisval[j]=sqrt(pow((rt[i].sit[j+1].x_position-rt[i].sit[j].x_position),2)+pow((rt[i].sit[j+1].y_position-rt[i].sit[j].y_position),2));
timval[j]=ddisval[j]/rt[i].speed;//cout<<rt[i].sit[j].name-'A'<<" "<<timval<<" "<<rt[i].sit[j+1].name-'A'<<endl;
if(j==0)dep_he[j]=timval[j];else dep_he[j]=dep_he[j-1]+timval[j];
}point[rt[i].sit[0].name-'A'].mp[rt[i].route_num]=make_pair(0,dep_he[rt[i].site_num-2]);
for(int j=0;j<rt[i].site_num-1;j++)
{
li.insertEdge(rt[i].sit[j].name-'A',rt[i].sit[j+1].name-'A',rt[i].route_num,ddisval[j],timval[j],rt[i].ticket_price,rt[i].dep_ti_interval,dep_he[j],dep_he[rt[i].site_num-2]-dep_he[j]);
}
}
}
//插入或者查找时都选择了空间换时间
dijkstra实现思路:
//:最小堆 邻接点 标记数组
//:最短路径 ,直接跑dij
if(dis[now->sit_num]>dis[x]+now->disval)
{
dis[now->sit_num]=dis[x]+now->disval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
//:最小时间 (不考虑等车)
if(dis[now->sit_num]>dis[x]+now->timval)
{
dis[now->sit_num]=dis[x]+now->timval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
//:最小时间 (考虑等车) 利用结构体struct point 记录 mp[id]=pair<double, double> 然后存点时正向1反向 0区分一下,根据中转站u的下一个点获得1/0,根据u找到point[u].mid[u.route_num].first/point[u].mid[u.route_num].second ,获取该线路车发站到中转站的时间t,然后根据该线路发车间隔dep_ti_interval和到达该站已经经过的时间dis[u],计算需要等待的时间
+画个图举个例子:
松弛操作:
if(np_r[x]==now->route_num)//同条线路不需要换乘
{ if(dis[now->sit_num]>dis[x]+now->timval)
{
dis[now->sit_num]=dis[x]+now->timval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else//换乘
{ double t=0;
if(now->index) t=point[x].mp[now->route_num].first;//正向 起点到该点的时间
else t=point[x].mp[now->route_num].second;double timei=0;
if(dis[x]<=t) timei=t-dis[x];
else
{
timei=(now->dep_ti_interval)-((int)(dis[x]-t)%(now->dep_ti_interval)+(dis[x]-t)-(int)(dis[x]-t));
}
if(dis[now->sit_num]>dis[x]+timei+now->timval)
{
dis[now->sit_num]=dis[x]+timei+now->timval;
pairNode<double>pp;pp.sit_num=now->sit_num;
pp.val=dis[now->sit_num];q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
//: 最小花费 因(因为多条线路的票价相同、一个点可以属于多条路线、票价相同的不同路线也得进行计算,同一路线不许计算,
所以根据路线在进行松弛操作时判断线路号是否相同,相同则不加票价,即加0,不同加上对应的票价。
*标记数组flag解决两点之间多条线路问题
if(np_r[x]==now->route_num)
{
if(dis[now->sit_num]>dis[x])
{
dis[now->sit_num]=dis[x];pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else
{
if(dis[now->sit_num]>dis[x]+now->priceval)
{
dis[now->sit_num]=dis[x]+now->priceval;
pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
dij完整代码:
void dij(int s,int _dij,int t)
{ // output();
memset(np_r,0,sizeof(np_r));memset(np_v,0,sizeof(np_v));
double dis[100]; minHeap<pairNode<double> >q;bool flag[100];//前去点 线路号记录
while(q.size())q.pop();memset(flag,0,sizeof(flag));
for(int i=0;i<100;i++) dis[i]=inf;
dis[s]=0;np_v[s]=-1;np_r[s]=-1;pairNode<double>p;p.sit_num=s;p.val=0;q.push(p);
while(q.size())
{
int x=q.top().sit_num;q.pop();
if(x==t)break;
if(flag[x])continue;flag[x]=1;
for(chainNode *now=aList[x].firstNode;now!=NULL;now=now->next)
{
if(_dij==2)//_dij=1时 最短距离
{
if(dis[now->sit_num]>dis[x]+now->disval)
{
dis[now->sit_num]=dis[x]+now->disval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else if(_dij==3) //最小时间(不考虑等车)
{
if(dis[now->sit_num]>dis[x]+now->timval)
{
dis[now->sit_num]=dis[x]+now->timval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else if(_dij==4)//等车 最小时间
{
if(np_r[x]==now->route_num)//同条线路不需要换乘
{ if(dis[now->sit_num]>dis[x]+now->timval)
{
dis[now->sit_num]=dis[x]+now->timval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else//换乘
{ double t=0;
if(now->index) t=point[x].mp[now->route_num].first;//正向 起点到该点的时间
else t=point[x].mp[now->route_num].second;double timei=0;
if(dis[x]<=t) timei=t-dis[x];
else
{ timei=(now->dep_ti_interval)-((int)(dis[x]-t)%(now->dep_ti_interval)+(dis[x]-t)-(int)(dis[x]-t));
}
if(dis[now->sit_num]>dis[x]+timei+now->timval)
{
dis[now->sit_num]=dis[x]+timei+now->timval;
pairNode<double>pp;pp.sit_num=now->sit_num;
pp.val=dis[now->sit_num];q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
}
else if(_dij==5)//最小花费
{
if(np_r[x]==now->route_num)
{
if(dis[now->sit_num]>dis[x])
{
dis[now->sit_num]=dis[x];pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else
{
if(dis[now->sit_num]>dis[x]+now->priceval)
{
dis[now->sit_num]=dis[x]+now->priceval;
pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
}
}
}
}
递归输出最优路线:
void print(int t)
{
if(np_v[t]==-1)
{char c=t+'A';cout<<c;return;
}
print(np_v[t]);char c=t+'A';
cout<<"--->"<<c<<"(线路"<<np_r[t]<<")";
}
主程序设计:
int main()
{ cout<<" 公交线路优化查询"<<endl;
cout<<" -----------------------------------------------------"<<endl;
cout<<" | |"<<endl;
cout<<" | 主菜单 |"<<endl;
cout<<" | 1.输入数据(可在过程中增加线路) |"<<endl;
cout<<" | 2.查询最短距离路径 |"<<endl;
cout<<" | 3.查询最少时间路径(不考虑等车) |"<<endl;
cout<<" | 4.查询最少时间路径(考虑等车时间) |"<<endl;
cout<<" | 5.查询最少花费路径 |"<<endl;
cout<<" | 6.退出系统 |"<<endl;
cout<<" -----------------------------------------------------"<<endl;
int n;linkedGraph li;cout<<"请输入选择序号(如果是第一步请选择输入数据):"<<endl;freopen("innn.txt","r",stdin);
while(cin>>n)
{
if(n==6) return 0;
else if(n==1)init(li);//输入线路信息
else
{ while(n<1||n>5)
{
cout<<"请输入主菜单中的选择序号2-6"<<endl;cin>>n;
if(n==6) return 0; if(n>=1&&n<=5)break;
}if(n==1) init(li);
else
{
cout<<"请输入起始站和终点站:"<<endl;char a,b;cin>>a>>b;int s=a-'A';int t=b-'A';
li.dij(s,n,t);cout<<"查询的结果路线为:";li.print(t);
}
}cout<<endl;
cout<<"是否还要继续?请输入YES or N0"<<endl;char str[10];cin>>str;
if(str=="NO") return 0;
cout<<"请输入选择序号(如果是第一步请选择输入数据):"<<endl;
}
}
完整代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<map>
# define inf 10000
using namespace std;
template<class T>
struct site//站点
{
char name;
T x_position;
T y_position;
};
template<class T>
struct route//路线
{
int route_num;
int ticket_price;
int dep_ti_interval;
int speed;
int site_num;
site<T> *sit;
route() {}
void rout()
{
sit=new site<T>[site_num+5];
}
};
struct po
{
map<int,pair<double,double> >mp;//mp[id]=pair<double,double>
}point[100];
struct chainNode
{
//顶点号 //线路号 //边距离 //边时间 //边票价
int sit_num;
int route_num;
double disval;
double timval;
int priceval;
int dep_ti_interval;
bool index;
chainNode *next;
chainNode() {}
chainNode(int _sit_num,int _route_num,double _disval,double _timval,int _priceval,int de_i,bool _index, chainNode* next)
:sit_num(_sit_num),route_num(_route_num),disval(_disval),timval(_timval),priceval(_priceval),dep_ti_interval(de_i),index(_index)
{ this->next = next;}
};
class chain
{
public:
chainNode* firstNode;
int listsize;
chain();
~chain();
void insert(int v2,int rout_num,double disv,double timv,int priv,int d_i,bool index);
int size()
{
return listsize;
}
};
chain::chain()
{
firstNode = NULL;
listsize=0;
}
chain::~chain()
{
while (firstNode != NULL)
{
chainNode* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
void chain::insert(int v2,int rout_num,double disv,double timv,int priv,int d_i,bool index)
{
firstNode = new chainNode(v2,rout_num,disv,timv,priv,d_i,index,firstNode);listsize++;
}
template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
if (newLength < 0)
return;
T* temp = new T[newLength];
int number = min(oldLength, newLength);
copy(a, a + number, temp);
delete [] a;
a = temp;
}
template<class T>
struct pairNode //pairNode<int>pairNode<int> p(val,v)
{
T val;int sit_num;
bool operator>(const pairNode& a)
{
return val>a.val;
}
bool operator<=(const pairNode&a)
{
return val<=a.val;
}
bool operator<(const pairNode& a)
{
return val<a.val;
}
operator=(const pairNode &a)
{
val=a.val;sit_num=a.sit_num;
}
};
template<class T>
class minHeap
{
public:
minHeap(int initialCapacity = 1000);
~minHeap() {delete [] heap;}
bool empty() const {return heapSize == 0;}
int size() const
{return heapSize;}
const T& top()
{
return heap[1];
}
void pop();
void push(const T);
void initialize(T *, int);
void deactivateArray()
{heap = NULL; arrayLength = heapSize = 0;}
void output(ostream& out) const;
private:
int heapSize; // number of elements in queue
int arrayLength; // queue capacity + 1
T *heap; // element array
};
template<class T>
minHeap<T>::minHeap(int initialCapacity)
{
arrayLength = initialCapacity + 1;
heap = new T[arrayLength];
heapSize = 0;
}
template<class T>
void minHeap<T>::push(const T theElement)
{
if (heapSize == arrayLength - 1)
{
changeLength1D(heap, arrayLength, 2 * arrayLength);
arrayLength *= 2;
}
int currentNode = ++heapSize;
while (currentNode != 1 && heap[currentNode / 2] > theElement)
{
heap[currentNode] = heap[currentNode / 2];
currentNode /= 2;
}
heap[currentNode] = theElement;
}
template<class T>
void minHeap<T>::pop()
{
if (heapSize == 0)
return;
heap[1].~T();
T lastElement = heap[heapSize--];
int currentNode = 1,
child = 2;
while (child <= heapSize)
{
if (child < heapSize && heap[child] > heap[child + 1])
child++;
if (lastElement <= heap[child])
break;
heap[currentNode] = heap[child];
currentNode = child;
child *= 2;
}
heap[currentNode] = lastElement;
}
template<class T>
void minHeap<T>::initialize(T *theHeap, int theSize)
{
delete [] heap;
heap = theHeap;
heapSize = theSize;
for (int root = heapSize / 2; root >= 1; root--)
{
T rootElement = heap[root];
int child = 2 * root;
while (child <= heapSize)
{
if (child < heapSize && heap[child] > heap[child + 1])
child++;
if (rootElement <= heap[child])
break;
heap[child / 2] = heap[child];
child *= 2;
}
heap[child / 2] = rootElement;
}
}
class linkedGraph
{
protected:
chain *aList; //存图
int np_v[100];
int np_r[100];
public:
linkedGraph()
{
aList=new chain[100];
}
~linkedGraph() {delete [] aList;}
void insertEdge(int v1,int v2,int rout_num,double disv,double timv,int priv,int d_i,double d_h1,double d_h2)
{
aList[v1].insert(v2,rout_num,disv,timv,priv,d_i,1);//正向
aList[v2].insert(v1,rout_num,disv,timv,priv,d_i,0);//反向
point[v2].mp[rout_num]=make_pair(d_h1,d_h2);
}
/* void output()
{ for(int i=0;i<=7;i++)
{
for(chainNode *now=aList[i].firstNode;now!=NULL;now=now->next)
{
cout<<now->priceval<<" ";
}cout<<endl;
}
}*/
void dij(int s,int _dij,int t)
{ // output();
memset(np_r,0,sizeof(np_r));memset(np_v,0,sizeof(np_v));
double dis[100]; minHeap<pairNode<double> >q;bool flag[100];//前去点 线路号记录
while(q.size())q.pop();memset(flag,0,sizeof(flag));
for(int i=0;i<100;i++) dis[i]=inf;
dis[s]=0;np_v[s]=-1;np_r[s]=-1;pairNode<double>p;p.sit_num=s;p.val=0;q.push(p);
while(q.size())
{
int x=q.top().sit_num;q.pop();
if(x==t)break;
if(flag[x])continue;flag[x]=1;
for(chainNode *now=aList[x].firstNode;now!=NULL;now=now->next)
{
if(_dij==2)//_dij=1时 最短距离
{
if(dis[now->sit_num]>dis[x]+now->disval)
{
dis[now->sit_num]=dis[x]+now->disval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else if(_dij==3) //最小时间(不考虑等车)
{
if(dis[now->sit_num]>dis[x]+now->timval)
{
dis[now->sit_num]=dis[x]+now->timval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else if(_dij==4)//等车 最小时间
{
if(np_r[x]==now->route_num)//同条线路不需要换乘
{ if(dis[now->sit_num]>dis[x]+now->timval)
{
dis[now->sit_num]=dis[x]+now->timval;pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else//换乘
{ double t=0;
if(now->index) t=point[x].mp[now->route_num].first;//正向 起点到该点的时间
else t=point[x].mp[now->route_num].second;double timei=0;
if(dis[x]<=t) timei=t-dis[x];
else
{ timei=(now->dep_ti_interval)-((int)(dis[x]-t)%(now->dep_ti_interval)+(dis[x]-t)-(int)(dis[x]-t));
}
if(dis[now->sit_num]>dis[x]+timei+now->timval)
{
dis[now->sit_num]=dis[x]+timei+now->timval;
pairNode<double>pp;pp.sit_num=now->sit_num;
pp.val=dis[now->sit_num];q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
}
else if(_dij==5)//最小花费
{
if(np_r[x]==now->route_num)
{
if(dis[now->sit_num]>dis[x])
{
dis[now->sit_num]=dis[x];pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
else
{
if(dis[now->sit_num]>dis[x]+now->priceval)
{
dis[now->sit_num]=dis[x]+now->priceval;
pairNode<double>pp;pp.sit_num=now->sit_num;pp.val=dis[now->sit_num];
q.push(pp);np_v[now->sit_num]=x;np_r[now->sit_num]=now->route_num;
}
}
}
}
}
}
void print(int t)
{
if(np_v[t]==-1)
{char c=t+'A';cout<<c;return;
}
print(np_v[t]);char c=t+'A';
cout<<"--->"<<c<<"(线路"<<np_r[t]<<")";
}
};
void init(linkedGraph& li)
{ //<100条线路
cout<<"请输入线路的个数:"<<endl;
int num;cin>>num;route<int>rt[100];
for(int i=1;i<=num;i++)
{
cout<<"请输入第"<<i<<"条线路号:"<<endl;cin>>rt[i].route_num;
cout<<"请输入该条线路站点的个数:"<<endl;cin>>rt[i].site_num;rt[i].rout();
cout<<"请输入站点名称及位置坐标:(站点名称用大写字母表示,从'A'开始命名)"<<endl;
for(int j=0;j<rt[i].site_num;j++)
{
cin>>rt[i].sit[j].name;cin>>rt[i].sit[j].x_position;cin>>rt[i].sit[j].y_position;
}cout<<"请输入发车时间间隔及车速和票价:"<<endl;cin>>rt[i].dep_ti_interval>>rt[i].speed>>rt[i].ticket_price;
double dep_he[100];double ddisval[100];double timval[100];memset(dep_he,0,sizeof(dep_he));memset(ddisval,0,sizeof(ddisval));
memset(timval,0,sizeof(timval));
for(int j=0;j<rt[i].site_num-1;j++)
{
ddisval[j]=sqrt(pow((rt[i].sit[j+1].x_position-rt[i].sit[j].x_position),2)+pow((rt[i].sit[j+1].y_position-rt[i].sit[j].y_position),2));
timval[j]=ddisval[j]/rt[i].speed;//cout<<rt[i].sit[j].name-'A'<<" "<<timval<<" "<<rt[i].sit[j+1].name-'A'<<endl;
if(j==0)dep_he[j]=timval[j];else dep_he[j]=dep_he[j-1]+timval[j];
}point[rt[i].sit[0].name-'A'].mp[rt[i].route_num]=make_pair(0,dep_he[rt[i].site_num-2]);
for(int j=0;j<rt[i].site_num-1;j++)
{
li.insertEdge(rt[i].sit[j].name-'A',rt[i].sit[j+1].name-'A',rt[i].route_num,ddisval[j],timval[j],rt[i].ticket_price,rt[i].dep_ti_interval,dep_he[j],dep_he[rt[i].site_num-2]-dep_he[j]);
}
}
}
int main()
{ cout<<" 公交线路优化查询"<<endl;
cout<<" -----------------------------------------------------"<<endl;
cout<<" | |"<<endl;
cout<<" | 主菜单 |"<<endl;
cout<<" | 1.输入数据(可在过程中增加线路) |"<<endl;
cout<<" | 2.查询最短距离路径 |"<<endl;
cout<<" | 3.查询最少时间路径(不考虑等车) |"<<endl;
cout<<" | 4.查询最少时间路径(考虑等车时间) |"<<endl;
cout<<" | 5.查询最少花费路径 |"<<endl;
cout<<" | 6.退出系统 |"<<endl;
cout<<" -----------------------------------------------------"<<endl;
int n;linkedGraph li;cout<<"请输入选择序号(如果是第一步请选择输入数据):"<<endl;freopen("innn.txt","r",stdin);
while(cin>>n)
{
if(n==6) return 0;
else if(n==1)init(li);//输入线路信息
else
{ while(n<1||n>5)
{
cout<<"请输入主菜单中的选择序号2-6"<<endl;cin>>n;
if(n==6) return 0; if(n>=1&&n<=5)break;
}if(n==1) init(li);
else
{
cout<<"请输入起始站和终点站:"<<endl;char a,b;cin>>a>>b;int s=a-'A';int t=b-'A';
li.dij(s,n,t);cout<<"查询的结果路线为:";li.print(t);
}
}cout<<endl;
cout<<"是否还要继续?请输入YES or N0"<<endl;char str[10];cin>>str;
if(str=="NO") return 0;
cout<<"请输入选择序号(如果是第一步请选择输入数据):"<<endl;
}
}