第5章第2节-城市地图-图的深度优先遍历

/*
图的基本概念:图就是有N个顶点和M条边组成的集合。
图分为有向图和无向图,如果给图的每条边规定一个方向,那么得到的图称为有向图,其边也称为有向边,
在有向图中,与一个点相关联的边有出边和入边之分,而与一个有向边关联的两个点也有始点和终点之分。
在寻找最短路径问题上,有向图和无向图所得到结果可能不一样,例如本题
有向图最短路径:1->2->5,长度为9。无向图最短路径:1->3->5,长度为7
题目:已知有5个城市和8条公路,用5*5矩阵存储这些信息,矩阵中大于0的数字表示可以从a到达b且之间的距离
就为此数字表示的距离,∞表示无法从a到达b,约定一个城市自己到达自己的距离是0。
求1号城市到5号城市的最短距离
*/
#include "stdio.h"
int min = 99999999,book[101],n,e[101][101];//这里我们用99999999表示正无穷大

//cur是当前所在城市的编号,dis是当前已走过的路程
void dfs(int cur, int dis)
{
    int j;
    //如果当前走过的路程已经大于之前找到的最短路程,则没必要再继续往下尝试了,立即返回
    if(dis > min)
    {
        return;
    }
    if(cur == n)//判断是否到达了目标城市
    {
        if(dis < min)
        {
            min = dis;//更新最小值
        }
        return;
    }

    for(j = 1; j <= n; j++)//从1号城市到n号城市依次尝试
    {
        //判断当前城市cur到城市j是否有路,并判断城市j是否在已经走过的路径中
        if(e[cur][j] != 99999999 && e[cur][j] != 0 && book[j] == 0)
        {
            book[j] = 1;//标记城市j已在路径中
            dfs(j,dis + e[cur][j]);//从城市j再出发,继续寻找目标城市
            book[j] = 0;//深搜此处很重要,之前一步探索完毕后,取消对城市j的标记 
        }
    }
    return;
}

int main()
{
    int i,j,m,a,b,c;
    scanf("%d %d",&n,&m);
    //初始化二维矩阵
    for(i = 1;i <= n;i++)
    {
        for(j = 1;j <= n;j++)
        {
            if(i == j)
            {
                e[i][j] = 0;
            }
            else
            {
                e[i][j] = 99999999;//我们这里假设99999999为正无穷大
            }
        }
    }
    //读入城市间的道路
    for(i = 1;i <= m;i++)
    {
        scanf("%d %d %d",&a,&b,&c);
        e[a][b] = c;//这里是有向图,所以e[b][a]不要赋值
    }

    //从1号城市出发
    book[1] = 1;//标记1号城市已经在路劲中
    dfs(1,0);//1表示当前所在城市编号,0表示当前已走过的路程
    printf("%d\n",min );//打印1号城市到5号城市的最短路径

    getchar();getchar();
    return 0;
}
/*
示例输入:
5 8     //5个城市8条路
1 2 2   //表示1号城市可以到达2号城市,路程为2
1 5 10
2 3 3
2 5 7
3 1 4
3 4 4 
4 5 5
5 3 3
示例输出:
9
*/

猜你喜欢

转载自blog.csdn.net/perfect_zdq/article/details/89295706