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


    摘自《啊哈算法》:小哼和小哈一同坐飞机去旅游,他们现在位于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;
    }

    结果如下:

  • 相关阅读:
    Leetcode645.Set Mismatch错误的集合
    Leetcode622.Design Circular Queue设计循环队列
    Leetcode628.Maximum Product of Three Numbers三个数的最大乘积
    Leetcode633.Sum of Square Numbers平方数之和
    Leetcode617.Merge Two Binary Trees合并二叉树
    Leetcode606.Construct String from Binary Tree根据二叉树创建字符串
    SQL Sever实验二 交互式 SQL
    [bzoj2124]等差子序列_线段树_hash
    [bzoj4084][Sdoi2015]双旋转字符串_hash
    [bzoj1708][Usaco2007 Oct]Money奶牛的硬币_动态规划_背包dp
  • 原文地址:https://www.cnblogs.com/lxt1105/p/6440360.html
Copyright © 2020-2023  润新知