7-1 最短路径-Dijkstra

城市的道路四通八达,我们经常需要查找从某地出发到其他地方的路径,当然我们希望能最快到达。现得到去每个地方需要花费的时间,现请你编写程序,计算从特定地点出发到所有城市之间的最短时间。

输入格式:

输入的第一行给出城市数目N (1≤N≤10)和道路数目M和1(表示有向图)或0(表示无向图);

接下来的M行对应每个城市间来往所需时间,每行给出3个正整数,分别是两个城市的编号(从1编号到N)和来往两城市间所需时间。最后一行给出一个编号,表示从此编号地点出发。

输出格式:

输出从特定地点出发到达所有城市(按编号1-编号N顺序输出)的距离(用编号1->编号**: 表示 ),如果无路,请输出no path。每个城市占一行。

输入样例:

5 5 1
1 2 2
1 4 8
2 3 16
4 3 6
5 3 3
1

输出样例:

1->1:0
1->2:2
1->3:14
1->4:8
1->5:no path

———————————————————————————————————————————

记录一些,自己抄书的疑惑和理解。 

最开始是自己做的,记不清算法了,最后没用纳入集合的方法,直接嵌套循环做的

但是第三个样例过不了。后来抄书用纳入集合的方法,就过了,但是还是理解了很长时间。

#include<iostream>
#define MAXX 1000
using namespace std;
int mapp[15][15];
int numWay;
int numCity;
int type;

void type1cin(){ //有向图
    for(int i=0;i<15;i++)
        for(int j=0;j<15;j++){
            mapp[i][j]=MAXX;
            if(i==j) mapp[i][j]=0;
        }
    
    for(int i=0;i<numWay;i++){
        int tempA,tempB;
        cin>>tempA>>tempB;
        cin>>mapp[tempA][tempB];
    }
}

void type0cin(){  //无向图
    for(int i=0;i<15;i++)
        for(int j=0;j<15;j++){
            mapp[i][j]=MAXX;
            if(i==j) mapp[i][j]=0;
        }
    
    for(int i=0;i<numWay;i++){
        int tempA,tempB;
        cin>>tempA>>tempB;
        cin>>mapp[tempA][tempB];
        mapp[tempB][tempA]=mapp[tempA][tempB];
    }
}


int main(){
    cin>>numCity>>numWay>>type;
    if(type) type1cin();
    else type0cin();

    int first;
    cin>>first;
    int record[15];
    bool internal[15]={false};
    
    for(int i=0;i<15;i++) record[i]=mapp[first][i];
    internal[first]=true;

        //纳入集合时,因为是从小到大选择纳入点的
        //记录外,不会有比所记录的纳入点最短路径,更短的纳入点路径
        //此时记录的纳入点最短路径,就是最短路径
        //例子:到a点的路径有,2(b节点)+4和3(c节点)+2;
        //此时先纳入b节点,记录下2+4路径
        //然后因为3<6,所以纳入c节点,记录下3+2
        //然后两两对比就会选择3+2的路径,纳入a节点
        
    for(int i=0;i<numCity;i++){
        int tempMin=MAXX;
        int tempUse=first;
        for(int j=1;j<=numCity;j++){
            if((!internal[j])&&record[j]<tempMin){
                tempMin=record[j];
                tempUse=j;
            }
        }
        internal[tempUse]=true;
        for(int j=1;j<=numCity;j++){
            if((!internal[j])&&mapp[tempUse][j]!=MAXX){
                if(record[tempUse]+mapp[tempUse][j]<record[j]){
                    record[j]=record[tempUse]+mapp[tempUse][j];
                }
            }
        }
    }

    
    for(int i=1;i<=numCity;i++){
        if(record[i]!=MAXX)cout<<first<<"->"<<i<<":"<<record[i]<<endl;
        else cout<<first<<"->"<<i<<":"<<"no path"<<endl;
    }
    return 0;
}

//record[i],i到first的最短距离
//每次更新内容:
//如果mapp[i][j],record[i]+mapp[i][j]<record[j],
//  record[j]=record[i]+mapp[i][j];

//注意,record[i]要在record[j]之前弄好
//所以要用纳入集合的方式


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值