校园导游咨询系统

//校园导游咨询系统

#include<stdio.h>
#include<malloc.h>

#define MAX 30  //顶点最大个数
#define NUM_N 20 //景点名字(英文)的最多字数
#define NUM_I 100//景点简介(英文)的最多字数
#define TRUE 1
#define FALSE 0
#define INFINITY 1000
typedef enum{DG,DN,UDG,UDN} Graphkind; //图的类型
typedef struct arccell  //定义表示弧的邻接矩阵
{
 int adj; 
 int *info;  //弧的相关信息
}arccell,adjmatrix[MAX][MAX];
typedef struct
{
 int symbol; //存放景点代码
 char *name; //存放景点名字
 char *introduction;//存放景点简介
}node;
typedef struct  //定义一个图类型
{
 node vexs[MAX];  //图的顶点信息
 adjmatrix arcs;  //图邻接矩阵
 int vexnum,arcnum; //图中点和边的个数
 Graphkind kind;  //图的种类
}mgraph;

typedef int pathmatrix_DJIK[MAX][MAX];//存放从一点到各点的路径
typedef int shortpathtable[MAX]; //存放从一点到各点的最短路径长度
 pathmatrix_DJIK p1;
    shortpathtable d1;
///

typedef int pathmatrix_FLOYD[MAX][MAX][MAX];//存放任意两点的路径
typedef int distancmatrix[MAX][MAX];//存放任意两点最短路径的长度
    pathmatrix_FLOYD p2;
    distancmatrix d2;
///

void  main()
{
 //变量定义
 mgraph g;
 ///
 //函数声明
 int locatevex(mgraph g,int v);
 int createUDN(mgraph &G);
 void shortpath_DJIK(mgraph G,int k,pathmatrix_DJIK &P,shortpathtable &D);
 void print_DJIK(mgraph G,pathmatrix_DJIK P,shortpathtable D);
    void shortpath_FLOYD(mgraph G,pathmatrix_FLOYD &P,distancmatrix &D);
 void print_FLOYD(mgraph G,pathmatrix_FLOYD P,distancmatrix D);
 void search(mgraph G);
 void ctrl(mgraph G);
    ///
    createUDN(g);//调用构造图的函数
    while(1)
      {ctrl(g);}//重复调用流程控制函数
}

 

//找出值为v的顶点在图的存储数组中的索引
int locatevex(mgraph g,int v)
{
 for(int i=0;i<g.vexnum;++i)
  if(g.vexs[i].symbol==v)return i;
}

//此函数计划从文件读取数据
int createUDN(mgraph &G)    //构造无向网
{
 int i,j,k,h;
 int v1,v2,w;
 G.vexnum=6;
 G.arcnum=8;
 
 //图中顶点数据录入
 for(h=0;h<G.vexnum;++h)
    {
   G.vexs[h].name=(char *)malloc(NUM_N*sizeof(char));
   G.vexs[h].introduction=(char *)malloc(NUM_I*sizeof(char));
       }
 G.vexs[0].symbol=1;
 G.vexs[0].name="北门";
 G.vexs[0].introduction="这是我校的北大门,具有悠久的历史.";

 G.vexs[1].symbol=2;
 G.vexs[1].name="八教";
 G.vexs[1].introduction="这是学校的第八教学楼,其中教学设施配备齐全.为同学们创造了良好的学习条件.";

 G.vexs[2].symbol=3;
 G.vexs[2].name="桔园";
 G.vexs[2].introduction="这是个学生宿舍园区,这里环境优雅,条件舒适.为同学们创造了良好的生活条件.";

    G.vexs[3].symbol=4;
 G.vexs[3].name="田家炳";
 G.vexs[3].introduction="这是学校的行政管理中心.";

 G.vexs[4].symbol=5;
 G.vexs[4].name="图书馆";
 G.vexs[4].introduction="这是学校在北校区的图书馆,其中藏书非常丰富";

 G.vexs[5].symbol=6;
 G.vexs[5].name="第一运动场";
 G.vexs[5].introduction="这是学校的第一运动场,设施一流齐全,为同学们创造了良好的娱乐场所.";
    /
 /
 //图中边的数据录入
 for(i=0;i<G.vexnum;++i)//初始化邻接矩阵
  for(j=0;j<G.vexnum;++j)
    {
     G.arcs[i][j].adj=INFINITY;
     G.arcs[i][j].info=0;
     if(i==j)G.arcs[i][j].adj=0;
           }
 G.arcs[0][1].adj=300;
    G.arcs[0][3].adj=300;
 G.arcs[0][5].adj=150;
 G.arcs[1][3].adj=100;
 G.arcs[3][4].adj=70;
 G.arcs[3][2].adj=350;
 G.arcs[2][4].adj=380;
 G.arcs[4][5].adj=100;
 for(i=0;i<G.vexnum;++i)
  for(j=0;j<G.vexnum;++j)
   if(G.arcs[i][j].adj==INFINITY)
    G.arcs[i][j].adj=G.arcs[j][i].adj;
   /
 return 1;
}

//输出菜单选项的函数
void print()
{
 printf("**********************MENU************************/n");
 printf("  查询景点信息请输入1;/n");
 printf("  查询到从北大门到各个景点的最短路径请输入2;/n");
 printf("  查询学校任意两个景点信息请输入3;/n");
 printf("**************************************************/n");
 printf("   北门:1            八教:2           桔园:3/n");
 printf("   田家炳:4          图书馆:5         第一运动场:6/n");
 printf("**************************************************/n");
}

//求从v0到各个顶点的最短路径,用P返回路径,用D返回各路径的总权值
void shortpath_DJIK(mgraph G,int k,pathmatrix_DJIK &P,shortpathtable &D)
{
 int v,v0,w,i,j;   
 int final[MAX]; //用此数组表示某个顶点是否已经并入s集合,其中final[i]表示G中索引为i的顶点
 v0=locatevex(G,k);//求数值为k的顶点在G中的索引
 for(v=0;v<G.vexnum;++v)
 {
       final[v]=FALSE; //初始化s集合为空集
    D[v]=G.arcs[v0][v].adj; //初始化D[i]为v0到i顶点的权
    for(w=0;w<G.vexnum;++w)
     P[v][w]=FALSE;  //初始化路径
    if(D[v]<INFINITY)
    {P[v][v0]=TRUE;P[v][v]=TRUE;}
 }
 D[v0]=0;
 final[v0]=TRUE; //初始化,v0顶点属于s集
 //开始主循环
 for(i=1;i<G.vexnum;++i)
 {
    int min;
    min=INFINITY;  //给min赋一个较大的值以便比较
    for(w=0;w<G.vexnum;++w)
     if(!final[w])
      if(D[w]<min){v=w;min=D[w];}//求出距离v0顶点最近的顶点在G中的索引w,并把v0到它的权赋给D[w]
    final[v]=TRUE;  //将v顶点并入s集合
    for(j=0;j<G.vexnum;++j)
     if(!final[j]&&(min+G.arcs[v][j].adj<D[j]))
     {
      D[j]=min+G.arcs[v][j].adj;
      for(int h=0;h<G.vexnum;++h)P[j][h]=P[v][h];
      P[j][j]=TRUE;
     }
 }
}
//输出起点到各个顶点的最小长度和经过的顶点的函数
void print_DJIK(mgraph G,pathmatrix_DJIK P,shortpathtable D)
{
 int i,j;
 for(i=0;i<G.vexnum;++i)
 {
  if(D[i]==1000)printf("/n从北校门到%s无路径./n",G.vexs[i].name);
  else if(D[i]==0);
  else
  {
   printf("/n从北校门到%s的最短路径长度为:%d/n经过的景点有:",G.vexs[i].name,D[i]);
      for(j=0;j<G.vexnum;++j)
    if(P[i][j]!=0)printf("%s ",G.vexs[j].name);
   printf("/n");
  }
 }
 printf("/n");
}

//求任意两个顶点间的最短路径,用P返回路径,用D返回路径的权值
//若P[v][w][u]为TRUE则表明u为v到w的当前最短路径中的点
void shortpath_FLOYD(mgraph G,pathmatrix_FLOYD &P,distancmatrix &D)
{
 int v,w,u,i;
 for(v=0;v<G.vexnum;++v)
  for(w=0;w<G.vexnum;++w)
  {
   D[v][w]=G.arcs[v][w].adj;//初始化表示各边权值的矩阵
   for(u=0;u<G.vexnum;++u)P[v][w][u]=FALSE;  //初始化表示路径的矩阵
   if(D[v][w]<INFINITY)  //从v到w有直接路径
    {P[v][w][v]=TRUE;P[v][w][w]=TRUE;} //将v和w在路径矩阵中标示出来
  }//for
//开始查找最短路径
  for(u=0;u<G.vexnum;++u)
   for(v=0;v<G.vexnum;++v)
    for(w=0;w<G.vexnum;++w)
     if(D[v][u]+D[u][w]<D[v][w])
     {
      D[v][w]=D[v][u]+D[u][w];
      for(i=0;i<G.vexnum;++i)
       P[v][w][i]=P[v][u][i] || P[u][w][i];
     }//if
}//shortpath_FLOYD

//将两个顶点的最短路径显示出来的函数
void print_FLOYD(mgraph G,pathmatrix_FLOYD P,distancmatrix D)
{
 int i,a,b,m,n;
 printf("依次输入您要查询的两个景点:/n");
 scanf("%d%d",&a,&b);
 m=locatevex(G,a);
 n=locatevex(G,b);
 if(D[m][n]==1000)printf("从%s到%s无路径/n",G.vexs[m].name,G.vexs[n].name);
 else
 {
  printf("从%s到%s的长度为:%d/n经过的景点有:",G.vexs[m].name,G.vexs[n].name,D[m][n]);
   for(i=0;i<G.vexnum;++i)
    if(P[m][n][i]==TRUE)printf("%s  ",G.vexs[i].name); 
     }
 printf("/n");
}

 

//查询某个景点信息的函数
void search(mgraph G)
{
 int n,i;
 printf("输入您要查询景点的代码:/n");
 scanf("%d",&n);
 for(i=0;i<G.vexnum;++i)
  if(n==G.vexs[i].symbol)
  {printf("景点名称:%s/n景点代码:%d/n景点简介:/n%s/n",G.vexs[i].name,G.vexs[i].symbol,G.vexs[i].introduction);return;}
 printf("这里没有您输入的景点代码,请核实./n");
}

//流程控制的函数
void ctrl(mgraph G)
{
 int i;
 print();
 printf("请选择:/n");
 scanf("%d",&i);
 switch(i)
 {
 case 1:{search(G);break;}
 case 2:{shortpath_DJIK(G,1,p1,d1);print_DJIK(G,p1,d1);break;}
 case 3:{shortpath_FLOYD(G,p2,d2);print_FLOYD(G,p2,d2);break;}
 }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值