最小飞机换乘(Dijkstra)

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#include<cstring>
#include<iomanip>
    using namespace std;
int INF=9999999;
template<class T>
class MGraph
{
public:
    MGraph(int mSize);
    ~MGraph();
    bool Insert(int u,int v);
    bool Remove(int u,int v);
    bool Exist(int u,int v) const;
    void DFS();
    void BFS();
    void Dijkstra(int v,T *d,int *path);
    void Floyd(int d[][100],int path[][100]);
    void Prim(int k,int *nearest,T *lowcost);
private:
    int n,e;
    T **a;
    int Choose(int *d,bool *s);
    void DFS(int v,bool *visited);
    void BFS(int v,bool *visited);
};
template<class T>
MGraph<T>::MGraph(int mSize)
{
    n=mSize;
    e=0;
    a=new T*[n];
    for(int i=0;i<n;i++)
    {
        a[i]=new T[n];
        for(int j=0;j<n;j++)
            a[i][j]=INF;
        a[i][i]=0;
    }
}
template<class T>
MGraph<T>::~MGraph()
{
    for(int i=0;i<n;i++)
        delete []a[i];
    delete []a;
}
template<class T>
bool MGraph<T>::Exist(int u,int v) const
{
    if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==INF)
        return false;
    else return true;
}
template<class T>
bool MGraph<T>::Insert(int u,int v)
{
    if(u<0||v<0||u>n-1||v>n-1||u==v ) return false;
    if(a[u][v]!=INF) return false;
    a[u][v]=1;
    e++;
    return true;
}
template<class T>
bool MGraph<T>::Remove(int u,int v)
{
    if(u<0||v<0||u>n-1||v>n-1||u==v||a[u][v]==INF)
        return false;
    a[u][v]=INF;
    e--;
    return true;
}
template<class T>
void MGraph<T>::DFS()
{
    bool *visited=new bool[n];
    memset(visited,false,sizeof(visited));
    for(int i=0;i<n;i++)
        if(visited[i]==false)
            DFS(i,visited);
    cout<<endl;
    delete []visited;
}
template<class T>
void MGraph<T>::DFS(int v,bool *visited)
{
    visited[v]=true;
    cout<<v<<" ";
    for(int i=0;i<n;i++)
    {
        if(a[v][i]!=INF&&visited[i]==false)
            DFS(i,visited);
    }
}
template<class T>
void MGraph<T>::BFS()
{
    bool *visited=new bool[n];
    memset(visited,false,sizeof(visited));
    for(int i=0;i<n;i++)
        if(visited[i]==false)
            BFS(i,visited);
    cout<<endl;
    delete []visited;
}
template<class T>
void MGraph<T>::BFS(int v,bool *visited)
{
    queue<int> q;
    visited[v]=true;
    q.push(v);
    while(!q.empty())
    {
        v=q.front();
        q.pop();
        cout<<v<<" ";
        for(int i=0;i<n;i++)
            if(visited[i]==false&&a[v][i]!=INF)
            {
                visited[i]=true;
                q.push(i);
            }
    }
}
template<class T>
int MGraph<T>::Choose(int *d,bool *s)
{
    int i,minpos;
    T min;
    min=INF;
    for(int i=0;i<n;i++)
        if(d[i]<=min&&!s[i])
        {
            min=d[i];
            minpos=i;
        }
    return minpos;
}
template<class T>
void MGraph<T>::Dijkstra(int v,T *d,int *path)
{
    if(v<0||v>n-1)
        return;
    bool *s=new bool[n];
    for(int i=0;i<n;i++)
    {
        s[i]=false;
        d[i]=a[v][i];
        if(i!=v&&d[i]<INF)
            path[i]=v;
        else
            path[i]=-1;
    }
    s[v]=true;
    d[v]=0;
    for(int i=1;i<n;i++)
    {
        int k=Choose(d,s);
        s[k]=true;
        for(int w=0;w<n;w++)
        {
            if(!s[w]&&d[k]+a[k][w]<d[w])
            {
                d[w]=d[k]+a[k][w];
                path[w]=k;
            }
        }
    }
}

int main()
{
    int n;
    cout<<"请输入城市个数:"<<endl;
    cin>>n;
    MGraph<int> G(n);
    int m;
    cout<<"请输入航线个数:"<<endl;
    cin>>m;
    cout<<"请输入m条航线的起点和终点:\n"<<endl;
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        G.Insert(x,y);
    }
    cout<<"请输入你出发地和目的地:"<<endl;
    int x,y;
    cout<<"出发地:";
    cin>>x;
    cout<<"目的地:";
    cin>>y;
    int *d=new int[n];
    int *path=new int[n];
    G.Dijkstra(x,d,path);
    if(d[y]==INF)
    {
        cout<<"没有换乘方案"<<endl;
    }
    else
    {
        cout<<"最少换乘次数为:\n"<<d[y]<<endl;
        int *record=new int[n+1];
        int j=0;
        while(y!=x)
        {
            record[j++]=y;
            y=path[y];
        }
        record[j++]=x;
        reverse(record,record+j);
        cout<<"换乘方案为:\n"<<endl;
        for(int i=0;i<j;i++)
        {
            if(i==0) cout<<record[i];
            else cout<<"->"<<record[i];
        }
        cout<<endl;
        cout<<endl;
        delete []record;
    }
    delete []d;
    delete []path;
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值