厦门大学校园导游系统(图论)
1、源代码
由之前的Dijstra算法和Floyd算法改造
#include <iostream>
#include<stdlib.h>
#include<queue>
#include<stdio.h>
using namespace std;
void pipei(int i);
using namespace std;
typedef int ArcCell; //直接存放权值
typedef struct{
ArcCell** arcs; //邻接矩阵,二维数组
int vexnum,arcnum; //图中当前顶点数和弧数
int *info; //顶点向量,与邻接矩阵的数组下标对应,顶点的相关信息,可修改数据结构进行添加信息
}MGraph;
MGraph Graph;
//创建邻接矩阵
void CreatGraph(){
Graph.vexnum=11;
Graph.arcnum=12;
Graph.arcs=(ArcCell**)malloc((Graph.vexnum+1)*sizeof(ArcCell*)); //动态开辟二维数组,0号单元不用
Graph.info=(int*)malloc((Graph.vexnum+1)*sizeof(int));
for(int i=0;i<=Graph.vexnum;i++)
Graph.arcs[i]=(ArcCell*)malloc((Graph.vexnum+1)*sizeof(ArcCell));
for(int i=0;i<=Graph.vexnum;i++)
for(int j=0;j<=Graph.vexnum;j++)
Graph.arcs[i][j]=0; //邻接矩阵全部置0,初始化
Graph.arcs[1][2]=200;
Graph.arcs[2][1]=200;
Graph.arcs[1][3]=100;
Graph.arcs[3][1]=100;
Graph.arcs[3][5]=100;
Graph.arcs[5][3]=100;
Graph.arcs[3][4]=200;
Graph.arcs[4][3]=200;
Graph.arcs[4][6]=100;
Graph.arcs[6][4]=200;
Graph.arcs[6][8]=200;
Graph.arcs[8][6]=200;
Graph.arcs[4][7]=200;
Graph.arcs[7][4]=200;
Graph.arcs[8][9]=300;
Graph.arcs[9][8]=200;
Graph.arcs[7][9]=400;
Graph.arcs[9][7]=200;
Graph.arcs[7][10]=100;
Graph.arcs[10][7]=200;
Graph.arcs[9][11]=100;
Graph.arcs[11][9]=200;
Graph.arcs[10][11]=400;
Graph.arcs[11][10]=200;
}
void view( ) //浏览校园地图
{
system("cls");
printf("\t 厦门大学 \n");
printf("\t --------------------------------------------------------|\n");
printf("\t| 1 | 2 | 面朝大海,春暖花开 |\n");
printf("\t| 演武场 | 演武大桥 | ------------ |\n");
printf("\t| 3 ----welcome----- |\n");
printf("\t| 明培体育馆 --------------- ‖-------------------- |\n");
printf("\t| | 5 科艺中心 | |\n");
printf("\t|========= | | |\n");
printf("\t| 4 | 6 | |8 芙蓉餐厅| |\n");
printf("\t| 嘉庚楼群 | 芙蓉湖 | |\n");
printf("\t| ‖ | | |\n");
printf("\t========= ==============================================|\n");
printf("\t|------- |\n");
printf("\t| |‖ ‖ |\n");
printf("\t| 图 |‖ ‖ |\n");
printf("\t| 7 书 |‖ ‖ |\n");
printf("\t| 馆 |‖ ‖ ‖ |9 勤业餐厅| ‖ |\n");
printf("\t|======================================================== |\n");
printf("\t| -------------- |\n");
printf("\t| | | 11 |\n");
printf("\t| | 10 南校门 | |芙蓉隧道| |\n");
printf("\t -------------------------------------------------------- \n");
printf("\t 输入1遍历所在位置到景点的距离. \n");
printf("\t 输入2遍历所有位置的距离. \n");
}
//Dijkstra算法(从某个源点到其余各顶点的最短路径)
/* 最短路径类型定义 */
#define INF 10000 //定义无穷大
void Dijkstra(MGraph G, int v0)
{
int set[G.vexnum+1];
int min,i,j,v;
int tmp[G.vexnum+1],k;
int path1[G.vexnum+1]; //path[i]表示从源点到顶点i之间最短路径的前驱节点
int dist1[G.vexnum+1]; //记录源点到顶点i之间的最短路径长度,dist的初值为arcs[v0][i]
for(i=1;i<=G.vexnum;i++){//数组初始化
if(G.arcs[v0][i])
dist1[i]=G.arcs[v0][i]; //dist1[i]:v0到i的最短路径长度
else dist1[i]=INF; //dist为无穷大
set[i]=0; //set[i]:标记数组,标记各顶点是否已加入路径
if(G.arcs[v0][i])
path1[i]=v0; //path1[i]:保存从v0到vi路径上vi的前一个顶点
else
path1[i]=-1; //代表v0到vi中间不经过任何顶点(可能不通,也可能是自身)
}
set[v0]=1;
path1[v0]=-1;
for(i=1;i<=G.vexnum;i++){ //初始化结束,关键操作开始(判断其余G1.vexnum-1个顶点)
min=10000;
for(j=1;j<=G.vexnum;j++){ //选出v0到剩余顶点中最短的一条路径
if(!set[j] && dist1[j]<min){
v=j;
min = dist1[j]; //v0到剩余顶点的最短路径<v0, v>
}
}
set[v]=1; //将顶点v加入最短路径
for(j=1;j<=G.vexnum;j++){ //判断v的加入是否会造就v0到剩余顶点的更短路径
if(!set[j] && min && G.arcs[v][j] && (min+G.arcs[v][j])<dist1[j]){
dist1[j]=min+G.arcs[v][j];
path1[j]=v;
}
}
}
//输出路径
for(i=1; i<=G.vexnum; i++){
if(v0!=i)
{
pipei(v0);cout<<"到";pipei(i);cout<<"的路径为:";
if(path1[i]==-1)
printf("×");
else{
tmp[0] = 0; //计数路径上的顶点个数
if(v0!=i){
k = i;
do{
tmp[0]++;
tmp[tmp[0]] = k;
k = path1[k];
}while(path1[k]!=-1);
}
if(tmp[0]){
for(j=tmp[0];j>=1;j--)
pipei(tmp[j]);
//printf("%d ", G.info[tmp[j]]); //tmp数组记录路径并输出
}
}
printf(",路程为:");
if(dist1[i]==INF)
printf("∞\n");
else
printf("%2d\n", dist1[i]);
}
}
}
void pipei(int i){
switch(i)
{
case 1 :printf("演武场.");break;
case 2 :printf("演武大桥.");break;
case 3 :printf("明培体育馆.");break;
case 4 :printf("嘉庚楼群.");break;
case 5 :printf("科艺中心.");break;
case 6 :printf("芙蓉湖.");break;
case 7 :printf("图书馆.");break;
case 8 :printf("芙蓉餐厅.");break;
case 9 :printf("勤业餐厅.");break;
case 10 :printf("南校门.");break;
case 11 :printf("芙蓉隧道.");break;
}
}
//Floyd算法求各顶点之间最短路径
void Floyd(MGraph G)
{
int i, j, k;
int path[20][G.vexnum+1];
int dist[20][G.vexnum+1];
int tmp[G.vexnum+1];
for(i=1;i<=G.vexnum;i++){ //赋初值
for(j=1; j<=G.vexnum; j++){
if(G.arcs[i][j])
dist[i][j] = G.arcs[i][j];
else dist[i][j]=INF;
path[i][j] = -1;
}
}
for(k=1;k<=G.vexnum;k++){ //以k为中间点检测各对顶点间距离
for(i=1;i<=G.vexnum;i++){
for(j=1;j<=G.vexnum;j++){
if(i!=j && dist[i][k]!=INF && dist[k][j]<INF && dist[i][k]+dist[k][j]<dist[i][j])
{
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = k;
}
}
}
}
//输出各对顶点之间路径
for(i=1;i<=G.vexnum;i++){
for(j=1; j<=G.vexnum; j++){
if(i!=j){
pipei(i);cout<<"到";pipei(j);cout<<"的最短路径为:";
//printf("%d 到 %d 的最短路径为:", G.info[i], G.info[j]);
if(dist[i][j]!=INF){
pipei(i);
//printf("%d ", G.info[i]);
k = i;
while(path[k][j]!=-1){
pipei(path[k][j]);
//printf("%d ", G.info[path[k][j]]);
k = path[k][j];
}
pipei(j);
//printf("%d ", G.info[j]);
}
else
printf("×");
printf(",路程为:");
if(dist[i][j]==INF)
printf("∞\n");
else
printf("%d\n", dist[i][j]);
}
}
}
}
int main() {
view();
int a,b;
scanf("%d",&b);
CreatGraph();
if(b==1) {
printf("输入现在所在的位置:");
scanf("%d", &a);
Dijkstra(Graph, a);
}else if(b==2) {
printf("\n");
Floyd(Graph);
}
return 0;
}
2、界面(不太友好啊)