最少转机---图的广度优先遍历

摘自《啊哈算法》:小哼和小哈一同坐飞机去旅游,他们现在位于1号城市,目标是5号城市,可是1号城市并没有直接到5号城市的直航. 不过小哼已经收集到了很多航班的信息,现在小哼希望找到一中乘坐方式,使得转机的次数最少?

输入数据样式为:

5 7 1 5

1 2

1 3

2 3

2 4

3 4

3 5

4 5

第一行:5表示有5个城市;7表示有7条航线;1表示起点城市;5表示目标城市

接下来7行每行是一条类似“a b”这样的数据表示城市a和城市b之间有航线,可以互相到达。

完整代码如下

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define INF 999999
struct note
{
    int x;     // 城市编号
    int s;     // 转机次数
};

int book[100];

int main(int argc, char const *argv[])
{
    int i, j, m, n, cur;
    int a, b, e[101][101];
    int head, tail;
    int start, end;
    int flag = 0;
    struct note que[2501];
    
    scanf_s("%d %d %d %d", &n, &m, &start, &end);
    //初始化二维矩阵
    for (i = 1; i <= n; ++i)
    {
        for (j = 1; j <= n; ++j)
        {
            if (i == j)
            {
                e[i][j] = 0;
            }
            else
            {
                e[i][j] = INF;
            }
        }
    }

    //读入城市之间的航班
    for (i = 1; i <= m; ++i)
    {
        scanf_s("%d %d", &a, &b);
        //注意这里是无向图
        e[a][b] = 1;
        e[b][a] = 1;
    }
    //队列初始化
    head = 1;
    tail = 1;
    //从start号城市出发,将start号城市加入队列
    que[tail].x = start;
    que[tail].s = 0;
    tail++;
    book[start] = 1;//标记start号城市已经在队列中
    //当队列不为空时循环
    while (head < tail)
    {
        cur = que[head].x;//当前队列中首城市的编号
        for (i = 1; i <= n; ++i) //从1到n依次尝试
        {
            //从城市cur到城市i是否有航班且判断城市i是否在队列中
            if (e[cur][i] == 1 && book[i] == 0)
            {
                //不在队列中,入队
                que[tail].x = i;
                que[tail].s = que[head].s + 1;//转机次数加1
                tail++;
                //标记城市i已经在队列中
                book[i] = 1;
            }

            if (que[tail - 1].x == end)       //达到目标城市, 退出循环
            {
                flag = 1;
                break;
            }
        }

        if (flag==1)
        {
            break;
        }

        head++; //有head++,才能继续扩展
    }

    //打印队列中末尾最后一个(目标城市)的转机次数
    //注意tail是指向队列队尾的下一个位置,所以这里需要减1
    printf("从%d城市转机到%d城市的最少转机次数是:\n", start, end);
    printf("%d\n", que[tail - 1].s);
    system("pause");
    return 0;
}

 

结果如下:

 

posted @ 2017-02-24 21:19  walanwalan  阅读(910)  评论(1编辑  收藏  举报