zoukankan      html  css  js  c++  java
  • 最少转机---图的广度优先遍历

    摘自《啊哈算法》:小哼和小哈一同坐飞机去旅游,他们现在位于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城市的最少转机次数是:
    ", start, end);
        printf("%d
    ", que[tail - 1].s);
        system("pause");
        return 0;
    }

    结果如下:

  • 相关阅读:
    第二十九课 循环链表的实现
    第二十八课 再论智能指针(下)
    第二十七课 再论智能指针(上)
    第二十六课 典型问题分析(Bugfix)
    普通new和placement new的重载
    leetcode 581. Shortest Unsorted Continuous Subarray
    leetcode 605. Can Place Flowers
    leetcode 219. Contains Duplicate II
    leetcode 283. Move Zeroes
    leetcode 217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/lxt1105/p/6440360.html
Copyright © 2011-2022 走看看