北京市旅游景点导游程序

#include<stdio.h>
#include<string.h>
#include<easyx.h>
#include<graphics.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
#include<mmsystem.h>
#include <iostream>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
#pragma comment(lib,"winmm.lib")
#define VNUM 11
#define N 100
#define M 1000
#define MAXSIZE 10
#define MAXCOST 1000000
#define min(a,b) ((a>b)?b:a)
static const int X = 1 << (VNUM - 1);
//保存顶点i到状态s最后回到起始点的最小距离
int dp[VNUM][X];
//保存路径
vector<int> path;
vector<int>v[VNUM];
IMAGE img[10];
//队列
typedef struct
{
    int data[MAXSIZE];
    int front;
    int rear;
    int queuesize;
}Queue;
//时间
typedef struct
{
    int hour;
    int minit;
}TIME;
//日期
typedef struct
{
    int month;
    int day;
}Date;
//开放时间
typedef struct
{
    Date beignday;
    Date endday;
    TIME begintime;
    TIME endtime;
    TIME lastenter_time;//最晚
}opentime;
//门票价格
typedef struct
{
    int adult;
    int child;
}PRICE;
//结点的信息
typedef struct
{
    char name[N];
    char intro[M];
    char location[N];
    PRICE price;
    opentime tim[5];
    char note[N];//特别注意
    int maxC;//最大容量
    char rec[N];
}Node;
//速度
typedef struct
{
    float v1;//步行
    float v2;//自驾
    float v3;//地铁公交
}Speed;
//图的定义
typedef struct
{
    Node vex[VNUM];
    int distance[VNUM][VNUM];
    int subway[VNUM][VNUM];
    int vexnum, arcnum;
}MGraph;
//栈的定义
typedef struct
{

    int data[VNUM];
    int top;
    int stacksize;
}Stack;
//迪杰斯特拉算法
typedef struct
{
    int distance;
    int path;
}ShortDist;
void InitQueue(Queue* Q);
int EmptyQueue(Queue Q);
int EnQueue(Queue* Q, int v);
int DeQueue(Queue* Q);
void creat_Graph(MGraph* G);
int switchchar_int(MGraph G, char ch[]);//将景点名称转换成结点序号
void Car_floyd(MGraph G, int dist[][VNUM], int path[][VNUM]);//弗洛伊德算法求两点之间的最短路径(自驾/打车路线)
void Sub_floyd(MGraph G, int dist[][VNUM], int path[][VNUM]);//弗洛伊德算法求两点之间的最短路径(地铁公交路线)
void dijstra(MGraph G, int v, ShortDist dist[]);//迪杰斯特拉算法找最短路径
void InitStack(Stack* S);
int EmptyStack(Stack S);
int EnStack(Stack* S, int e);
int DeStack(Stack* S);
void meanu();//主页菜单
void button(int x, int y, int w, int h, char text[]);//生成按钮
void outintro(MGraph G, int n);//输出景点简介
void mouseclick(MGraph G);//主页鼠标点击操作
void swap(MGraph* G, int n);//第n个结点与第0个结点交换
void TSP(MGraph G);//核心函数,求出动态规划dp数组
bool isVisited(bool visited[]);//判断结点是否都以访问,不包括0号结点
void getPath(MGraph G);//获取最优路径,保存在path中,根据动态规划公式反向找出最短路径结点
void printPath(MGraph G);//输出路径
int main()
{
    int i, j = 0, n = 0, m = 0, v, min[3] = { 0 };
    char ch[20];
    Queue Q;
    MGraph G;
    creat_Graph(&G);
    InitQueue(&Q);
    v = 0;
    //v= switchchar_int(G, ch);
    //LowCost lowcost[VNUM];
    //MSTGRAPH(G, v, lowcost);
    
    initgraph(1200, 700, SHOWCONSOLE);
    mciSendString("open 风.mp3", 0, 0, 0);
    mciSendString("play 风.mp3", 0, 0, 0);
    settextcolor(BLACK);
    meanu();
    mouseclick(G);
    getchar();
    return 0;
}

void InitQueue(Queue* Q)
{
    Q->front = 0;
    Q->rear = 0;
    Q->queuesize = MAXSIZE;
}
int EmptyQueue(Queue Q)
{
    if (Q.rear == Q.front) return 1;
    else return 0;
}
int EnQueue(Queue* Q, int v)
{
    if ((Q->rear + 1) % Q->queuesize == Q->front) return 0;
    Q->data[Q->rear] = v; Q->rear = (Q->rear + 1) % Q->queuesize; return 1;
}
int DeQueue(Queue* Q)
{
    int n;
    if (Q->rear == Q->front) return 0;
    n = Q->data[Q->front];
    Q->front = (Q->front + 1) % Q->queuesize;
    return n;
}

//创建图
void creat_Graph(MGraph* G)
{
    int i, j, k;
    strcpy_s(G->vex[0].name, "颐和园");
    strcpy_s(G->vex[0].intro, "颐和园是世界十大名园之一及传统造园艺术之大成界景周围的山水环境,既有皇家园林恢弘富力的气势,又充满了自然之趣,高度体现了中国园林虽由人作宛自天成的造园准则,主景区由万寿山,昆明湖组成,全园占地3.009平方公里,其中颐和园世界文化遗产区面积是2.97平方公里,水面约占3/4,园内现存各式宫殿,园林古建七万平方米,并以珍贵的文物藏品文明");
    strcpy_s(G->vex[0].location, "海淀区新建宫门路19号");
    strcpy_s(G->vex[0].rec, "清晏舫,画中游,听鹂馆,十七孔桥");
    G->vex[0].tim[0].beignday.month = 4;
    G->vex[0].tim[0].beignday.day = 1;
    G->vex[0].tim[0].endday.month = 10;
    G->vex[0].tim[0].endday.day = 31;
    G->vex[0].tim[0].begintime.hour = 6;
    G->vex[0].tim[0].begintime.minit = 0;
    G->vex[0].tim[0].endtime.hour = 20;
    G->vex[0].tim[0].endtime.minit = 0;
    G->vex[0].tim[0].lastenter_time.hour = 19;
    G->vex[0].tim[0].lastenter_time.minit = 0;
    G->vex[0].tim[1].beignday.month = 11;
    G->vex[0].tim[1].beignday.day = 1;
    G->vex[0].tim[1].endday.month = 3;
    G->vex[0].tim[1].endday.day = 31;
    G->vex[0].tim[1].begintime.hour = 6;
    G->vex[0].tim[1].begintime.minit = 30;
    G->vex[0].tim[1].endtime.hour = 19;
    G->vex[0].tim[1].endtime.minit = 0;
    G->vex[0].tim[1].lastenter_time.hour = 18;
    G->vex[0].tim[1].lastenter_time.minit = 0;
    G->vex[0].maxC = 100000;
    G->vex[0].price.adult = 30;
    G->vex[0].price.child = 15;
    strcpy_s(G->vex[0].note, "0");
    strcpy_s(G->vex[1].name, "故宫");
    strcpy_s(G->vex[1].intro, "故宫是明、清两代的皇宫,也叫紫荆城。故宫博物院位于北京市东城区,是中国最大的古代文化艺术博物馆,也是全国爱国主义教育示范基地、国家5A级旅游景区、世界三大宫殿之一。故宫有着文物78万件,加上新放进去的文物21万件,总数达到了近百万件,最珍贵的当属《清明上河图》。故宫著名的景点有午门、东华门、太和门三大殿。");
    strcpy_s(G->vex[1].location, "东城区景山前街4号");
    strcpy_s(G->vex[1].rec, "珍妃井,畅音阁,景仁宫 ");
    G->vex[1].tim[0].beignday.month = 4;
    G->vex[1].tim[0].beignday.day = 1;
    G->vex[1].tim[0].endday.month = 10;
    G->vex[1].tim[0].endday.day = 31;
    G->vex[1].tim[0].begintime.hour = 8;
    G->vex[1].tim[0].begintime.minit = 30;
    G->vex[1].tim[0].endtime.hour = 17;
    G->vex[1].tim[0].endtime.minit = 0;
    G->vex[1].tim[0].lastenter_time.hour = 16;
    G->vex[1].tim[0].lastenter_time.minit = 10;
    G->vex[1].tim[1].beignday.month = 11;
    G->vex[1].tim[1].beignday.day = 1;
    G->vex[1].tim[1].endday.month = 3;
    G->vex[1].tim[1].endday.day = 31;
    G->vex[1].tim[1].begintime.hour = 8;
    G->vex[1].tim[1].begintime.minit = 30;
    G->vex[1].tim[1].endtime.hour = 16;
    G->vex[1].tim[1].endtime.minit = 30;
    G->vex[1].tim[1].lastenter_time.hour = 15;
    G->vex[1].tim[1].lastenter_time.minit = 40;
    G->vex[1].maxC = 80000;
    G->vex[1].price.adult = 80;
    G->vex[1].price.child = 30;
    strcpy_s(G->vex[1].note, "周一不开放,法定节假日周一不闭馆!");
    strcpy_s(G->vex[2].name, "圆明园");
    strcpy_s(G->vex[2].intro, "圆明园位于北京市海淀区,是始建于清康熙四十六年,占地约3.5平方千米,由圆明园、长春园、绮春园组成,被誉为万园之园。圆明园也是皇家园林,皇帝在夏天的时候会来到这里办公、避暑,所以又称之为夏宫,在第二次鸦片战争的时候,圆明园遭到洗劫和焚烧,毁于一旦。");
    strcpy_s(G->vex[2].location, "海淀区清华西路28号");
    strcpy_s(G->vex[2].rec, "海晏堂,黄花镇,方壶胜境,西洋楼 ,五竹亭");
    G->vex[2].tim[0].beignday.month = 4;
    G->vex[2].tim[0].beignday.day = 1;
    G->vex[2].tim[0].endday.month = 10;
    G->vex[2].tim[0].endday.day = 31;
    G->vex[2].tim[0].begintime.hour = 6;
    G->vex[2].tim[0].begintime.minit = 0;
    G->vex[2].tim[0].endtime.hour = 20;
    G->vex[2].tim[0].endtime.minit = 0;
    G->vex[2].tim[0].lastenter_time.hour = 19;
    G->vex[2].tim[0].lastenter_time.minit = 0;
    G->vex[2].tim[1].beignday.month = 11;
    G->vex[2].tim[1].beignday.day = 1;
    G->vex[2].tim[1].endday.month = 3;
    G->vex[2].tim[1].endday.day = 31;
    G->vex[2].tim[1].begintime.hour = 6;
    G->vex[2].tim[1].begintime.minit = 30;
    G->vex[2].tim[1].endtime.hour = 19;
    G->vex[2].tim[1].endtime.minit = 0;
    G->vex[2].tim[1].lastenter_time.hour = 18;
    G->vex[2].tim[1].lastenter_time.minit = 0;
    G->vex[2].maxC = 22000;
    G->vex[2].price.adult = 108;
    G->vex[2].price.child = 94;
    strcpy_s(G->vex[2].note, "0");
    strcpy_s(G->vex[3].name, "北海公园");
    strcpy_s(G->vex[3].intro, "北海公园位于北京市中心,是古代皇家园林,占地约68.2万平方米,被评为全国重点文物保护单位和国家4A级旅游景点。在公园湖中间有一座琼华岛,在元朝的时候曾多次扩建琼华岛,还在岛上 修建了广寒殿等宫殿。 北海公园主要由 琼华岛、东岸和北岸景区组成。");
    strcpy_s(G->vex[3].location, "西城区文津街1号");
    strcpy_s(G->vex[3].rec, "琼华岛,小西天,九龙壁");
    G->vex[3].tim[0].beignday.month = 4;
    G->vex[3].tim[0].beignday.day = 1;
    G->vex[3].tim[0].endday.month = 10;
    G->vex[3].tim[0].endday.day = 31;
    G->vex[3].tim[0].begintime.hour = 6;
    G->vex[3].tim[0].begintime.minit = 0;
    G->vex[3].tim[0].endtime.hour = 21;
    G->vex[3].tim[0].endtime.minit = 0;
    G->vex[3].tim[0].lastenter_time.hour = 20;
    G->vex[3].tim[0].lastenter_time.minit = 30;
    G->vex[3].tim[1].beignday.month = 11;
    G->vex[3].tim[1].beignday.day = 1;
    G->vex[3].tim[1].endday.month = 3;
    G->vex[3].tim[1].endday.day = 31;
    G->vex[3].tim[1].begintime.hour = 6;
    G->vex[3].tim[1].begintime.minit = 30;
    G->vex[3].tim[1].endtime.hour = 20;
    G->vex[3].tim[1].endtime.minit = 0;
    G->vex[3].tim[1].lastenter_time.hour = 19;
    G->vex[3].tim[1].lastenter_time.minit = 30;
    G->vex[3].maxC = 32000;
    G->vex[3].price.adult = 89;
    G->vex[3].price.child = 82;
    strcpy_s(G->vex[3].note, "0");
    G->vexnum = VNUM;
    strcpy_s(G->vex[4].name, "恭王府");
    strcpy_s(G->vex[5].name, "什刹海");
    strcpy_s(G->vex[6].name, "清华");
    strcpy_s(G->vex[7].name, "北大");
    strcpy_s(G->vex[8].name, "军事博物馆");
    strcpy_s(G->vex[9].name, "鸟巢");
    strcpy_s(G->vex[10].name, "雍和宫");
    for (i = 0; i < G->vexnum; i++)
        for (j = 0; j < G->vexnum; j++)
        {
            G->distance[i][j] = MAXCOST;
            G->subway[i][j] = MAXCOST;
        }
    G->distance[0][2] = 1720;    G->distance[2][0] = 1720;
    G->distance[6][2] = 3700;  G->distance[2][6] = 3700;
    G->distance[7][2] = 6600;   G->distance[2][7] = 6600;
    G->distance[6][7] = 900;  G->distance[7][6] = 900;
    G->distance[5][7] = 12400;  G->distance[7][5] = 12400;
    G->distance[5][4] = 490;  G->distance[4][5] = 490;
    G->distance[4][3] = 780;   G->distance[3][4] = 780;
    G->distance[1][3] = 800;  G->distance[3][1] = 800;
    G->distance[0][8] = 11890;  G->distance[8][0] = 11890;
    G->distance[7][8] = 8000;  G->distance[8][7] = 8000;
    G->distance[5][8] = 8100;  G->distance[8][5] = 8100;
    G->distance[3][8] = 8500;  G->distance[8][3] = 8500;
    G->distance[5][9] = 10000;  G->distance[9][5] = 10000;
    G->distance[6][9] = 9000;  G->distance[9][6] = 9000;
    G->distance[10][9] = 6900;  G->distance[9][10] = 6900;
    G->distance[1][10] = 4900;  G->distance[10][1] = 4900;
    G->distance[3][10] = 5300;  G->distance[10][3] = 5300;
    G->distance[2][9] = 15000;  G->distance[9][2] = 15000;
    G->subway[0][2] = 3400;    G->subway[2][0] = 3400;
    G->subway[6][2] = 2000;  G->subway[2][6] = 2000;
    G->subway[7][2] = 4000;   G->subway[2][7] = 4000;
    G->subway[6][7] = 900;  G->subway[7][6] = 900;
    G->subway[5][7] = 8000;  G->subway[7][5] = 8000;
    G->subway[5][4] = 600;  G->subway[4][5] = 600;
    G->subway[4][3] = 780;   G->subway[3][4] = 780;
    G->subway[1][3] = 800;  G->subway[3][1] = 800;
    G->subway[0][8] = 11890;  G->subway[8][0] = 11890;
    G->subway[7][8] = 10600;  G->subway[8][7] = 10600;
    G->subway[5][8] = 9500;  G->subway[8][5] = 9500;
    G->subway[3][8] = 9500;  G->subway[8][3] = 9500;
    G->subway[1][8] = 12700;  G->subway[8][2] = 12700;
    G->subway[5][9] = 8500;  G->subway[9][5] = 8500;
    G->subway[6][9] = 8500;  G->subway[9][6] = 8500;
    G->subway[10][9] = 9600;  G->subway[9][10] = 9600;
    G->subway[1][10] = 5300;  G->subway[10][1] = 5300;
    G->subway[3][10] = 3830;  G->subway[10][3] = 3830;
    G->subway[2][9] = 10000;  G->subway[9][2] = 10000;
}

//将字符转换成结点序号
int switchchar_int(MGraph G, char ch[])
{
    int i, j;
    for (i = 0; i < G.vexnum; i++)
    {
        if (strcmp(G.vex[i].name, ch) == 0)
        {
            return i; break;
        }
    }
}

//弗洛伊德算法求两点之间的最短路径(开车)
void Car_floyd(MGraph G, int dist[][VNUM], int path[][VNUM])
{
    int i, j, k, m, n;
    for (i = 0; i < G.vexnum; i++)
        for (j = 0; j < G.vexnum; j++)
        {
            dist[i][j] = G.distance[i][j];
            path[i][j] = i;
            if (dist[i][j] == MAXCOST || dist[i][j] == 0)
                path[i][j] = -1;
        }
    for (k = 0; k < G.vexnum; k++)
        for (i = 0; i < G.vexnum; i++)
            for (j = 0; j < G.vexnum; j++)
                if (dist[i][k] + dist[k][j] < dist[i][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = k;
                }

}

//弗洛伊德算法求两点之间的最短路径(地铁公交)
void Sub_floyd(MGraph G, int dist[][VNUM], int path[][VNUM])
{
    int i, j, k, m, n;
    for (i = 0; i < G.vexnum; i++)
        for (j = 0; j < G.vexnum; j++)
        {
            dist[i][j] = G.subway[i][j];
            if (dist[i][j] == MAXCOST || dist[i][j] == 0)
                path[i][j] = -1;
            else
                path[i][j] = i;
        }
    for (k = 0; k < G.vexnum; k++)
        for (i = 0; i < G.vexnum; i++)
            for (j = 0; j < G.vexnum; j++)
                if (dist[i][k] + dist[k][j] < dist[i][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = k;
                }

}

//迪杰斯特拉算法找最短路径
void dijstra(MGraph G, int v, ShortDist dist[])
{
    int flag[N] = { 0 };
    int mincost, minpos, i;
    flag[v] = 1;
    for (i = 0; i < G.vexnum; i++)
    {
        dist[i].distance = G.distance[v][i];
        if (G.distance[v][i] != MAXCOST)
            dist[i].path = v;
        else dist[i].path = -1;
    }
    while (1)
    {
        minpos = v;
        mincost = MAXCOST;
        for (i = 0; i < G.vexnum; i++)
        {
            if (flag[i] == 0 && dist[i].distance < mincost)
            {
                mincost = dist[i].distance;
                minpos = i;
            }
        }
        if (mincost == MAXCOST) break;
        flag[minpos] = 1;
        for (i = 0; i < G.vexnum; i++)
            if (flag[i] == 0 && dist[minpos].distance + G.distance[minpos][i] < dist[i].distance)
            {
                dist[i].distance = dist[minpos].distance + G.distance[minpos][i];
                dist[i].path = minpos;
            }
    }
}

void InitStack(Stack* S)
{
    S->top = -1;
    S->stacksize = VNUM;
}
int EmptyStack(Stack S)
{
    if (S.top == -1) return 1;
    else return 0;
}
int EnStack(Stack* S, int e)
{
    S->top = S->top + 1;
    S->data[S->top] = e;
    return 1;
}
int DeStack(Stack* S)
{
    int e;
    e = S->data[S->top--];
    return e;
}

//生成按钮
void button(int x, int y, int w, int h, char text[])
{
    setlinecolor(WHITE);
    setlinestyle(PS_SOLID);
    roundrect(x, y, x + w, y + h, 10, 10);
    settextcolor(BLACK);
    settextstyle(30, 0, "华文琥珀");
    setbkmode(TRANSPARENT);//透明
    int width = textwidth(text);
    int height = textheight(text);
    outtextxy(x + ((w - width) / 2), y + ((h - height) / 2), text);
}

//菜单函数
void meanu()
{
    loadimage(&img[0], "back.jpg");
    loadimage(&img[1], "图1.jpg");
    loadimage(&img[2], "图2.jpg");
    putimage(0, 0, &img[0]);
    putimage(0, 0, &img[2]);
    settextcolor(WHITE);
    settextstyle(40, 0, "华文琥珀");
    setbkmode(TRANSPARENT);//透明
    char z[30] = "欢迎使用北京景点导游系统";
    char ex[4][20];
    strcpy_s(ex[0], "查询景点信息");
    strcpy_s(ex[1], "附近景点推荐");
    strcpy_s(ex[2], "路径规划");
    strcpy_s(ex[3], "全览规划");
    outtextxy(350, 50, z);
    button(360, 150, 400, 50, ex[0]);
    button(360, 200, 400, 50, ex[1]);
    button(360, 250, 400, 50, ex[2]);
    button(360, 300, 400, 50, ex[3]);
}

//输出简介
void outintro(MGraph G, int n)
{
    IMAGE mag;
    loadimage(&mag, "白板.jpg");
    putimage(200, 100, &mag);
    settextcolor(BLACK);
    settextstyle(20, 0, "华文琥珀");
    setbkmode(TRANSPARENT);//透明
    outtextxy(800, 115, G.vex[n].name);
    settextcolor(RGB(94,18,51));
    settextstyle(20, 0, "黑体");
    setbkmode(TRANSPARENT);//透明
    RECT r = { 655, 145,970,500 };
    drawtext(G.vex[n].intro, &r, DT_CENTER | DT_VCENTER | DT_WORDBREAK);
    char ch[N]; char index[N];
    strcpy_s(ch, "地址:");//地址信息
    strcat_s(ch, G.vex[n].location);
    outtextxy(655, 370,ch);
    strcpy_s(ch, "门票:");//门票信息
    strcat_s(ch, "成人:");
    sprintf_s(index, "%d",G.vex[n].price.adult);
    strcat_s(ch, index);
    strcat_s(ch, "元  ");
    strcat_s(ch, "儿童:");
    sprintf_s(index, "%d", G.vex[n].price.child);
    strcat_s(ch, index);
    strcat_s(ch, "元 ");
    outtextxy(655, 390, ch);
    outtextxy(655, 410, "开放时间:");//时间信息
    sprintf_s(index, "%d", G.vex[n].tim[0].beignday.month);
    strcpy_s(ch, index);
    strcat_s(ch, "月");
    sprintf_s(index, "%d", G.vex[n].tim[0].beignday.day);
    strcat_s(ch, index);
    strcat_s(ch, "日");
    strcat_s(ch, "-");
    sprintf_s(index, "%d", G.vex[n].tim[0].endday.month);
    strcat_s(ch, index);
    strcat_s(ch, "月");
    sprintf_s(index, "%d", G.vex[n].tim[0].endday.day);
    strcat_s(ch, index);
    strcat_s(ch, "日 ");
    sprintf_s(index, "%d", G.vex[n].tim[0].begintime.hour);
    strcat_s(ch, index);
    strcat_s(ch, ":");
    sprintf_s(index, "%2d", G.vex[n].tim[0].begintime.minit);
    strcat_s(ch, index);
    if (G.vex[n].tim[0].begintime.minit < 10)
        strcat_s(ch, "0");
    strcat_s(ch, "-");
    sprintf_s(index, "%2d", G.vex[n].tim[0].endtime.hour);
    strcat_s(ch, index);
    strcat_s(ch, ":");
    sprintf_s(index, "%2d", G.vex[n].tim[0].endtime.minit);
    strcat_s(ch, index);
    if (G.vex[n].tim[0].endtime.minit < 10)
        strcat_s(ch, "0");
    outtextxy(655, 430, ch);
    strcpy_s(ch, "最晚进入时间:");
    sprintf_s(index, "%d", G.vex[n].tim[0].lastenter_time.hour);
    strcat_s(ch, index);
    strcat_s(ch, ":");
    sprintf_s(index, "%2d", G.vex[n].tim[0].lastenter_time.minit);
    strcat_s(ch, index);
    if (G.vex[n].tim[0].lastenter_time.minit < 10)
        strcat_s(ch, "0");
    outtextxy(655, 450, ch);
    sprintf_s(index, "%2d", G.vex[n].tim[1].beignday.month);
    strcpy_s(ch, index);
    strcat_s(ch, "月");
    sprintf_s(index, "%2d", G.vex[n].tim[1].beignday.day);
    strcat_s(ch, index);
    strcat_s(ch, "日");
    strcat_s(ch, "-");
    sprintf_s(index, "%2d", G.vex[n].tim[1].endday.month);
    strcat_s(ch, index);
    strcat_s(ch, "月");
    sprintf_s(index, "%d", G.vex[n].tim[1].endday.day);
    strcat_s(ch, index);
    strcat_s(ch, "日 ");
    sprintf_s(index, "%2d", G.vex[n].tim[1].begintime.hour);
    strcat_s(ch, index);
    strcat_s(ch, ":");
    sprintf_s(index, "%2d", G.vex[n].tim[1].begintime.minit);
    strcat_s(ch, index);
    if (G.vex[n].tim[1].begintime.minit < 10)
        strcat_s(ch, "0");
    strcat_s(ch, "-");
    sprintf_s(index, "%2d", G.vex[n].tim[1].endtime.hour);
    strcat_s(ch, index);
    strcat_s(ch, ":");
    sprintf_s(index, "%2d", G.vex[n].tim[1].endtime.minit);
    strcat_s(ch, index);
    if (G.vex[n].tim[1].endtime.minit < 10)
        strcat_s(ch, "0");
    outtextxy(655, 470, ch);
    strcpy_s(ch, "最晚进入时间:");
    sprintf_s(index, "%2d", G.vex[n].tim[0].lastenter_time.hour);
    strcat_s(ch, index);
    strcat_s(ch, ":");
    sprintf_s(index, "%2d", G.vex[n].tim[1].lastenter_time.minit);
    strcat_s(ch, index);
    if (G.vex[n].tim[1].lastenter_time.minit < 10)
        strcat_s(ch, "0");
    outtextxy(655, 490, ch);
    strcpy_s(ch, "最大人流量:");
    sprintf_s(index, "%d", G.vex[n].maxC);
    strcat_s(ch, index);
    strcat_s(ch, "人");
    outtextxy(655, 510, ch);
    outtextxy(655, 530, "推荐重点游玩景点:");
    outtextxy(655, 550, G.vex[n].rec);

}

//主页鼠标点击操作
void mouseclick(MGraph G)
{
    IMAGE ph[5][8]; ShortDist dist[VNUM];
    float t1, t2, t3;
    int i, j = 0, k, n = 0, m = 0; char s[10]; char c[10]; char ch[N];
    int min[5] = { 0 }; int t, visited[VNUM] = { 0 };
    Speed sp; int d[VNUM], sb[VNUM];
    sp.v1 = 1.5; sp.v2 = 8.3; sp.v3 = 6.5;

    loadimage(&img[5], "地图.jpg");
    loadimage(&ph[1][1], "故宫1.jpg");
    loadimage(&ph[1][2], "故宫2.jpg");
    loadimage(&ph[1][3], "故宫3.jpg");
    loadimage(&ph[1][4], "故宫4.jpg");
    loadimage(&ph[1][5], "故宫5.jpg");
    loadimage(&ph[1][6], "故宫6.jpg");
    loadimage(&ph[1][7], "故宫7.jpg");
    loadimage(&ph[0][1], "颐和园1.jpg");
    loadimage(&ph[0][2], "颐和园2.jpg");
    loadimage(&ph[0][3], "颐和园3.jpg");
    loadimage(&ph[0][4], "颐和园4.jpg");
    loadimage(&ph[0][5], "颐和园5.jpg");
    loadimage(&ph[0][6], "颐和园6.jpg");
    loadimage(&ph[0][7], "颐和园7.jpg");
    loadimage(&ph[2][1], "圆明园1.jpg");
    loadimage(&ph[2][2], "圆明园2.jpg");
    loadimage(&ph[2][3], "圆明园3.jpg");
    loadimage(&ph[2][4], "圆明园4.jpg");
    loadimage(&ph[2][5], "圆明园5.jpg");
    loadimage(&ph[2][6], "圆明园6.jpg");
    loadimage(&ph[2][7], "圆明园7.jpg");
    loadimage(&ph[3][1], "北海1.jpg");
    loadimage(&ph[3][2], "北海2.jpg");
    loadimage(&ph[3][3], "北海3.jpg");
    loadimage(&ph[3][4], "北海4.jpg");
    loadimage(&ph[3][5], "北海5.jpg");
    loadimage(&ph[3][6], "北海6.jpg");
    loadimage(&ph[3][7], "北海7.jpg");
    loadimage(&img[4], "bk2.jpg");
    settextcolor(WHITE);

    while (1)
    {
        MOUSEMSG msg = GetMouseMsg();
        switch (msg.uMsg)
        {
        case WM_LBUTTONDOWN:
            //音乐打开
            if (msg.x < 70 && msg.y < 70)
            {
                mciSendString("pause 风.mp3", 0, 0, 0);
                loadimage(&img[1], "图1.jpg");
                putimage(0, 0, &img[1]);
            }

            //景点查询
            if (msg.x > 360 && msg.x < 760 && msg.y>150 && msg.y < 200)
            {
                // 定义字符串缓冲区,并接收用户输入
                InputBox(s, 10, "请输入查询的景点名称");
                n = switchchar_int(G, s);
                switch (n)
                {
                case 0:
                    outintro(G, 0);
                    for (i = 1; i < 8; i++)
                    {
                        putimage(210,110, &ph[0][i]);
                        Sleep(800);
                    }
                    break;
                case 1:
                    outintro(G, 1);
                    for (i = 1; i < 8; i++)
                    {
                        putimage(210, 110, &ph[1][i]);
                        Sleep(800);                        
                    }
                    break;
                case 2:
                    outintro(G, 2);
                    for (i = 1; i < 8; i++)
                    {
                        putimage(210, 110, &ph[2][i]);                        
                        Sleep(800);
                    }
                    break;
                case 3:
                    outintro(G, 3);
                    for (i = 1; i < 8; i++)
                    {
                        putimage(210, 110, &ph[3][i]);
                        Sleep(800);
                    }
                    break;
                }
            }

            //推荐附近景点
            if (msg.x > 360 && msg.x < 760 && msg.y>200 && msg.y < 250)
            {
                settextcolor(WHITE);
                settextstyle(30, 0, "宋体");
                InputBox(s, 10, "请输入当前所在位置");
                n = switchchar_int(G, s);
                dijstra(G, n, dist);
                m = 0; j = 0;
                for (i = 1; i < G.vexnum; i++)
                {
                    if (dist[i].distance < dist[m].distance)
                        m = i;
                    if (dist[i].distance < 1000)
                    {
                        min[j] = i;
                        j++;
                    }
                }
                putimage(200, 100, &img[4]);
                putimage(500, 250, &img[5]);
                strcpy_s(ch, G.vex[n].name);
                strcat_s(ch, "附近可以一起游玩的景点:");
                outtextxy(360, 160, ch);
                if (j == 0)
                {
                    outtextxy(360, 200, G.vex[m].name);
                
                }
                if (j != 0)
                {
                    for (i = 0; i < j; i++)
                        outtextxy(360, 200 + i * 50, G.vex[min[i]].name);
                }
            }

            //两点间的路径规划
            if (msg.x > 360 && msg.x < 760 && msg.y>250 && msg.y < 300)
            {
                int x, y;
                InputBox(s, 10, "请输入起点:");
                m = switchchar_int(G, s);
                InputBox(c, 10, "请输入终点:");
                n = switchchar_int(G, c);
                int lin[VNUM];
                int distan[VNUM][VNUM], dpath[VNUM][VNUM], sub[VNUM][VNUM], spath[VNUM][VNUM];
                Car_floyd(G, distan, dpath);
                Sub_floyd(G, sub, spath);
                char dex[N]; strcpy_s(ch, G.vex[m].name); strcat_s(ch, "到");
                strcat_s(ch, G.vex[n].name);
                strcat_s(ch, "全程");
                t1 = distan[m][n] / sp.v1;
                t2 = distan[m][n] / sp.v2;
                t3 = sub[m][n] / sp.v3;
                putimage(200, 100, &img[4]);
                putimage(500, 250, &img[5]);
                settextcolor(WHITE);
                settextstyle(30, 0, "宋体");
                i = 0; j = 0;
                Stack S; InitStack(&S);
                ShortDist dist[VNUM];
                dijstra(G, m, dist);
                y = n;
                while (dist[y].path != -1)
                {
                    EnStack(&S, y);
                    y = dist[y].path;
                }
                EnStack(&S, y);
                int rode[VNUM]; k = 0;
                while (!EmptyStack(S))
                {
                    rode[k] = DeStack(&S);
                    k++;
                }
                if (distan[m][n] < 1000)
                {
                    sprintf_s(dex, "%d", distan[m][n]);
                    strcat_s(dex, "米,");
                    strcat_s(ch, dex);
                    outtextxy(250, 160, ch);
                    t = t1 / 60;
                    sprintf_s(dex, "%d", t);
                    strcpy_s(ch, "推荐步行或骑行");
                    outtextxy(250, 200, ch);
                    strcpy_s(ch, "大约需要");
                    strcat_s(ch, dex);
                    strcat_s(ch, "分钟");
                    outtextxy(250, 240, ch);
                    for (i = 0; i < k; i++)
                    {
                        settextcolor(WHITE);
                        settextstyle(20, 0, "宋体");
                        outtextxy(250, 280, "游览路线如下");
                        outtextxy(250,300 + i * 20, G.vex[rode[i]].name);
                    }
                }
                else
                {
                    if (t2 < t3)
                    {
                        sprintf_s(dex, "%d", distan[m][n]);
                        strcat_s(dex, "米,");
                        strcat_s(ch, dex);
                        outtextxy(250, 160, ch);
                        t = t2 / 60;
                        sprintf_s(dex, "%d", t);
                        strcpy_s(ch, "推荐打车或自驾");
                        outtextxy(250, 200, ch);
                        strcpy_s(ch, "大约需要");
                        strcat_s(ch, dex);
                        strcat_s(ch, "分钟");
                        outtextxy(250, 240, ch);

                        for (i = 0; i < k; i++)
                        {
                            settextcolor(WHITE);
                            settextstyle(20, 0, "宋体");
                            outtextxy(250, 280, "游览路线如下");
                            outtextxy(250, 300 + i * 20, G.vex[rode[i]].name);
                        }
                    }
                    if (t2 > t3)
                    {
                        sprintf_s(dex, "%d", sub[m][n]);
                        strcat_s(dex, "米,");
                        strcat_s(ch, dex);
                        outtextxy(250, 160, ch);
                        t = t3 / 60;
                        sprintf_s(dex, "%d", t);
                        strcpy_s(ch, "推荐乘坐地铁公交");
                        outtextxy(250, 200, ch);
                        strcpy_s(ch, "大约需要");
                        strcat_s(ch, dex);
                        strcat_s(ch, "分钟");
                        outtextxy(250, 240, ch);
                        for (i = 0; i < k; i++)
                        {
                            settextcolor(WHITE);
                            settextstyle(20, 0, "宋体");
                            outtextxy(250, 280, "游览路线如下");
                            outtextxy(250, 300 + i * 20, G.vex[rode[i]].name);
                        }
                    }
                    if (t1 == t2)
                    {
                        sprintf_s(dex, "%d", distan[m][n]);
                        strcat_s(dex, "米,");
                        strcat_s(ch, dex);
                        outtextxy(250, 160, ch);
                        int a, b;
                        a = t2 / 60; b = t3 / 60;
                        strcpy_s(ch, "乘坐地铁公交");
                        outtextxy(250, 200, ch);
                        strcpy_s(ch, "大约需要");
                        sprintf_s(dex, "%d", b);
                        strcat_s(ch, dex);
                        strcat_s(ch, "分钟");
                        outtextxy(250, 240, ch);
                        strcpy_s(ch, "选择自驾或打车");
                        outtextxy(250, 280, ch);
                        strcpy_s(ch, "大约需要");
                        sprintf_s(dex, "%d", a);
                        strcat_s(ch, dex);
                        strcat_s(ch, "分钟");
                        outtextxy(250, 320, ch);
                        for (i = 0; i < k; i++)
                        {
                            settextcolor(WHITE);
                            settextstyle(20, 0, "宋体");
                            outtextxy(250, 360, "游览路线如下");
                            outtextxy(250, 380 + i * 20, G.vex[rode[i]].name);
                        }
                    }
                }
            }

            //全览规划
            if (msg.x > 360 && msg.x < 760 && msg.y>300 && msg.y < 350)
            {
                
                InputBox(s, 10, "请输入起点:");
                n = switchchar_int(G, s);
                swap(&G, n);
                TSP(G);
                getPath(G);
                putimage(200, 100, &img[4]);
                putimage(500, 250, &img[5]);
                settextcolor(WHITE);
                settextstyle(20, 0, "黑体");
                outtextxy(240, 150, "全览路线(游览顺序)如下:");
                printPath(G);

            }

            //返回菜单
            if (msg.x > 950 && msg.x < 1000 && msg.y>100 && msg.y < 150)
                meanu();
            break;

        case WM_RBUTTONDOWN:
            //音乐关闭
            if (msg.x < 70 && msg.y < 70)
            {
                mciSendString("play 风.mp3", 0, 0, 0);
                putimage(0, 0, &img[2]);
            }
            break;
        }
    }
}

//第n个结点与第0个结点交换
void swap(MGraph* G, int n)
{
    int temp,i,j;
    char ch[N];
    strcpy_s(ch, G->vex[0].name);
    strcpy_s(G->vex[0].name, G->vex[n].name);
    strcpy_s(G->vex[n].name, ch);
    for (i = 0; i < G->vexnum; i++)
    {
            temp = G->distance[n][i];
            G->distance[n][i] = G->distance[0][i];
            G->distance[i][n] = G->distance[0][i];
            G->distance[0][i] = temp;
            G->distance[i][0] = temp;
    }
    for (i = 0; i < G->vexnum; i++)
        for (j = 0; j < G->vexnum; j++)
            G->distance[0][0] = 0;
}

//核心函数,求出动态规划dp数组
void TSP(MGraph G)
{
    //初始化dp[i][0]
    for (int i = 0; i < VNUM; i++)
    {
        dp[i][0] = G.distance[i][0];
    }
    //求解dp[i][j],先跟新列在更新行
    for (int j = 1; j < X; j++)
    {
        for (int i = 0; i < VNUM; i++)
        {
            dp[i][j] = MAXCOST;
            //如果集和j(或状态j)中包含结点i,则不符合条件退出
            if (((j >> (i - 1)) & 1) == 1)
            {
                continue;
            }
            for (int k = 1; k < VNUM; k++)
            {
                //枚举集合j中的节点
                if (((j >> (k - 1)) & 1) == 0)
                {
                    //如果集合中没有节点k,退出
                    continue;
                }
                if (dp[i][j] > G.distance[i][k] + dp[k][j ^ (1 << (k - 1))])
                {  
                    //使用异或去掉集合j中的节点k。
                    dp[i][j] = G.distance[i][k] + dp[k][j ^ (1 << (k - 1))];
                }
            }
        }
    }

}

//判断结点是否都以访问,不包括0号结点
bool isVisited(bool visited[])
{
    for (int i = 1; i < VNUM; i++)
    {
        if (visited[i] == false)
        {
            return false;
        }
    }
    return true;

}

//获取最优路径,保存在path中,根据动态规划公式反向找出最短路径结点
void getPath(MGraph G)
{
    //标记访问数组
    bool visited[VNUM] = { false };
    //前驱节点编号
    int pioneer = 0, min = MAXCOST, S = X - 1, temp=0;
    //把起点结点编号加入容器
    path.push_back(0);

    while (!isVisited(visited))
    {
        for (int i = 1; i < VNUM ; i++)
        {
            if (visited[i] == false && (S & (1 << (i - 1))) != 0)
            {
                if (min > G.distance[pioneer][i] + dp[i][(S ^ (1 << (i - 1)))])
                {
                    min = G.distance[pioneer][i] + dp[i][(S ^ (1 << (i - 1)))];
                    temp = i;
                }
            }
        }
        pioneer = temp;
        path.push_back(pioneer);
        visited[pioneer] = true;
        S = S ^ (1 << (pioneer - 1));
        min = MAXCOST;
    }
}

//输出路径
void printPath(MGraph G)
{
    int i = 0; int v; char ch[200];
    strcpy_s(ch, "&");
    vector<int>::iterator  it = path.begin();
    for (it; it != path.end(); it++)
    {
        v = *it;
        strcat_s(ch, G.vex[v].name);
        strcat_s(ch, "--->");
    }
    //单独保存起点编号
    strcat_s(ch, G.vex[0].name);
    RECT r = { 240, 200,700,500 };
    drawtext(ch, &r, DT_LEFT | DT_VCENTER | DT_WORDBREAK);
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾画F

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值