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

标题:最少转机
标签:搜索 广度优先搜索
详情:

 

小哼和小哈一同坐飞机去旅游,他们现在位于1号城市,目标是5号城市,可是1号城市并没有到5号城市的直航。不过小哼已经收集了很多航班的信息,现在小哼希望找到一种乘坐方式,使得转机的次数最少,如何解决呢?

 

输入格式:
第一行的有两个整数n m s e,n表示有n个城市(城市编号为1~n),m表示有m条航线,s表示起点城市,e表示目标城市。
接下来m行每行是一条类似“a b”这样的数据表示城市a和城市b之间有航线,也就是说城市a和城市b之间可以相互到达
输出格式:
s号城市到e号目标城市,需要飞行几次?
限制:1<=n<=1000 
1<=m<=300000
样例:

输入

5 7 1 5
1 2
1 3
2 3
2 4
3 4
3 5
4 5

输出

2

#include <stdio.h>
#define maxn 1050
int ar[maxn][maxn], flag[maxn];
int n, m, s, e;
struct node{
    int s;
    int x;
}que[maxn];
int main()
{
    int i, j, a, b, head = 1, tail = 1, min = 99999999,flag1 = 0;
    scanf("%d %d %d %d", &n, &m, &s, &e);
    for(i = 1; i <= n; i++)
    {
        for(j = 1; j <= n; j++)
        {
            if(i == j) ar[i][j] = 0;
            else ar[i][j] = 99999999;
        }
    }
    for(i = 1; i <= m; i++)
    {
        scanf("%d %d", &a, &b);
        ar[a][b] = 1;  //无向图的特点,注意
        ar[b][a] = 1;
    }
    que[tail].x = s; //初始化要完整全面,不要初始化了队列忘了标记数组。
    que[tail].s = 0;
    tail++;
    flag[s] = 1;  // 标记数组初始化
    while(head < tail && tail <= n)
    {
        int cur = que[head].x;
        for(i = 1; i <= n; i++)
        {
            if(ar[cur][i] != 99999999 && flag[i] == 0)
            {
                que[tail].x = i;
                que[tail].s = que[head].s + 1;
                tail++;
                flag[i] = 1;
            }
            if(que[tail-1].x == e)  // 已经到了终点
            {
                flag1 = 1;
                break;
            }
        }
        if(flag1 == 1) break;
        if(tail > n) break;
        head++;
    }
    printf("%d", que[tail-1].s);

    return 0;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会根据你的要求进行回答。下面是对你的问题的回答: 这是一个典型的论问题,可以使用广度优先搜索(BFS)算法来解决。BFS 是一种遍历的算法,从起点开始,依次访问与之相邻的节点,直到找到目标节点或遍历完整个。 在这个问题中,我们可以使用邻接矩阵来表示,即使用一个二维数组来表示每个节点之间的连接关系。如果节点 i 和节点 j 之间存在边,则 `adjMatrix[i][j]` 的值为 1,否则为 0。 下面是实现 `int minFlightChanges(int** adjMatrix, int numVertices, int startVertex, int targetVertex)` 函数的步骤: 1. 初始化一个队列,将起始城市作为第一个元素入队。 2. 初始化一个数组,用于记录每个节点是否已经被访问过。初始时,所有节点都未被访问过。 3. 初始化一个数组,用于记录从起始城市到每个城市的最少转机次数。初始时,所有值都为无穷大,除了起始城市的值为 0。 4. 从队列中取出第一个元素,将其标记为已访问。 5. 遍历与当前城市相邻的所有城市,如果该城市未被访问过,则将其入队,并更新从起始城市到该城市的最少转机次数。 6. 重复步骤 4 和步骤 5,直到队列为空或找到目标城市。 7. 如果找到了目标城市,则返回从起始城市到目标城市的最少转机次数,否则返回 -1。 下面是完整的代码实现: ``` #include <queue> #include <limits.h> using namespace std; int minFlightChanges(int** adjMatrix, int numVertices, int startVertex, int targetVertex) { queue<int> q; q.push(startVertex); bool visited[numVertices] = {false}; visited[startVertex] = true; int dist[numVertices]; for (int i = 0; i < numVertices; i++) { dist[i] = INT_MAX; } dist[startVertex] = 0; while (!q.empty()) { int curr = q.front(); q.pop(); for (int i = 0; i < numVertices; i++) { if (adjMatrix[curr][i] == 1 && !visited[i]) { q.push(i); visited[i] = true; dist[i] = dist[curr] + 1; if (i == targetVertex) { return dist[i]; } } } } return -1; } ``` 该函数的时间复杂度为 O(V^2),其中 V 表示节点的数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值