图的最短路径

#include <string>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <stack>
#ifndef DEFINATION_H
#define DEFINATION_H

using namespace std;

struct destination{       //顶点的定义
    string node;
    string name;
    string info;
    destination(string a,string b,string c){
        node=a;
        name=b;
        info=c;
    }
    destination(){}
};

struct Edge{           //邻接表节点的定义
    int dest;         //另一节点位置
    int cost;         //权值
    Edge* link;       //下一条边链指针
    Edge(){};
    Edge(int a,int b){
        dest=a;
        cost=b;
        link=NULL;
    }
};

class Graph{
    int n;               //景点个数
    destination* V;      //顶点数组
    int **E;             //边
    Edge** Elink;         //邻接表
public:
    //从文件加载信息
    Graph(){
        ifstream fmap;
        ifstream finfo;
        fmap.open("D:/map.txt",ios::in);
        finfo.open("D:/attractions.txt",ios::in);
        int line=0,s;
        if (fmap.is_open())
        {
            string buf;
            while (getline(fmap,buf))
            {
                istringstream is(buf);
                if(line==0){
                    line++;
                    is>>n;
                    V=new destination[n];
                    E=(int**)new int*[n];
                    for(int j=0;j<n;j++)
                        E[j]=new int[n];
                }
                else{
                    int col=0;
                    while(is>>s){
                       E[line-1][col]=s;
                       col++;
                    }
                    line++;
                }
            }
        }
        else{
            cout<<"map.txt open error"<<endl;
            exit(1);
        }
        line=0;
        if(finfo.is_open())
        {
            string buffer,no,na,in;
            while (getline(finfo,buffer))
            {
                istringstream is(buffer);
                is>>no>>na>>in;
                V[line].node=no;
                V[line].name=na;
                V[line].info=in;
                line++;
            }
        }
        else{
            cout<<"file open error"<<endl;
            exit(1);
        }
        fmap.close();
        finfo.close();
    }
     //初始化邻接表
    string init(){
        string str="";
        char s[1000];
        Elink=new Edge*[n];
        for(int i=0;i<n;i++)
            Elink[i]=new Edge(i,0);
        for(int i=0;i<n;i++){
                Edge*p=Elink[i];
            for(int j=0;j<n;j++){
                if(E[i][j]>0){
                    Edge* newnode=new Edge(j,E[i][j]);
                    p->link=newnode;
                    p=p->link;
                }
            }
        }
        for(int i=0;i<n;i++){
            sprintf(s,"%s%-20s——> ",V[i].node.c_str(),V[i].name.c_str());
            str=str+s;
            Edge*p=Elink[i]->link;
            while(p!=NULL){
                str=str+V[p->dest].node+"("+std::to_string(p->cost)+"m)   ";
                p=p->link;
            }
        }
        return str;
    }
    //查询景点详细信息
    string showInfo(string findnode){
        string str="";
        for(int i=0;i<n;i++){
            if(findnode==V[i].node||findnode==V[i].name){
                str=str+V[i].node+V[i].name+":\n";
                str=str+"         "+V[i].info+"\n";
                return str;
            }
            str=str+"\n";
        }
        str="您的输入有误!\n";
        return str;
    }

    //查询两景点最短距离
    string finddist(string start,string endpoint){
        int s=0,e=0,cnt=0,x;
        int dist[n];
        int path[n];
        bool exist[n];
        for(int i=0;i<n;i++)
        {
            dist[i]=9999;
            exist[i]=false;
            path[i]=-1;
        }
        for(int i=0;i<n;i++){
            if(start==V[i].node)
                s=i;
            if(endpoint==V[i].node)
                e=i;
        }
        dist[s]=0;
        while(cnt<n){
            int minp=9999;
            for(int i=0;i<n;i++){
                if(dist[i]<minp&&exist[i]==false){
                        x=i;
                        minp=dist[i];
                }
            }
            exist[x]=true;
            for(int j=0;j<n;j++){
                if((dist[j]>dist[x]+E[x][j])&&E[x][j]>0){
                    path[j]=x;
                    dist[j]=dist[x]+E[x][j];
                }
            }
            cnt++;
            if(x==e)
                break;
        }
        if(dist[e]==9999){
            string res="未找到路线\n";
            return res;
        }
        string str=findpath(dist,path,s,e);
        string res="已为您规划好路线,全程"+std::to_string(dist[e])+"米\n";
        res+=str;
        return res;
    }
    /*寻找路径*/
    string findpath(int*dist,int*path,int s,int e){
        string result="";
        stack<int> sta;
        int p=e;
        while(p!=s){
            sta.push(path[p]);
            p=path[p];
        }
        while(sta.empty()==false){
            int x=sta.top();
            sta.pop();
            result=result+V[x].name+" -> ";
        }
        result=result+V[e].name+"\n";
        return result;
    }
   //游览全部景点
    string allvisit(string choice) {
        string str="";
        int start=-1;
        for(int i=0;i<n;i++){
            if(choice==V[i].node){
                start=i;
            }
        }
        if(start==-1){
            str="您的输入有误";
            return str;
        }
        int res[n],minres=9999,cnt=0;
        bool exist[n];
        for(int i=0;i<n;i++)
            exist[i]=false;
        res[0]=start;
        exist[start]=true;
        DFS(1,res,exist,&minres,0,&cnt);
        str=str+"已为您规划好最佳路线"+"     总长"+std::to_string(minres)+"米\n";
        for(int i=0;i<n-1;i++){
            str=str+V[res[i]].name+" --- ";
        }
        str=str+V[res[n-1]].name+"\n";
        return str;
    }
    void DFS(int t,int *res,bool*exist,int*minres,int curres,int *cnt) {
        if(t>=n){
            if(*minres>curres)
                *minres=curres;
            return;
        }
        for(int i=0;i<n;i++){
            if(E[res[t-1]][i]>0&&exist[i]==false){
                    res[t]=i;
                    curres+=E[res[t-1]][i];
                    exist[i]=true;
                    if(curres<*minres){
                        DFS(t+1,res,exist,minres,curres,cnt);
                    }
                    curres-=E[res[t-1]][i];
                    exist[i]=false;
            }
        }
    }
    //展示全部景点信息
    string showall(){
        string str="";
//        cout<<"代号  景点名称          简介"<<endl;
//        for(int i=0;i<n;i++){
//            cout<<V[i].node;
//            printf("  %-20s%s\n",V[i].name.c_str(),V[i].info.c_str());
//        }
        str=str+"各景点连接的路径(邻接表形式)\n";
        str=str+init();
        return str;
    }
};
#endif // DEFINATION_H

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

轻舟812

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

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

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

打赏作者

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

抵扣说明:

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

余额充值