访问所有节点的最短路径

847. 访问所有节点的最短路径

存在一个由 n 个节点组成的无向连通图,图中的节点按从 0n - 1 编号。

给你一个数组 graph 表示这个图。其中,graph[i] 是一个列表,由所有与节点 i 直接相连的节点组成。

返回能够访问所有节点的最短路径的长度。你可以在任一节点开始和停止,也可以多次重访节点,并且可以重用边。

示例 1:

**输入:**graph = [[1,2,3],[0],[0],[0]]
**输出:**4
**解释:**一种可能的路径为 [1,0,2,0,3]

示例 2:

**输入:**graph = [[1],[0,2,4],[1,3,4],[2],[1,2]]
**输出:**4
**解释:**一种可能的路径为 [0,1,4,2,3]

提示:

  • n == graph.length
  • 1 <= n <= 12
  • 0 <= graph[i].length < n
  • graph[i] 不包含 i
  • 如果 graph[a] 包含 b ,那么 graph[b] 也包含 a
  • 输入的图总是连通图

这个题目就和我们狄克斯特拉算法标记vis还是有区别的,我们的节点可以重复访问,我们不能对节点进行标记

class Solution {
public:
    int shortestPathLength(vector<vector<int>>& graph) {
        int n = graph.size();
        queue<tuple<int, int, int>> q;
        vector<vector<bool>> vis(n, vector<bool>(1 << n));
        // 那么从哪一个点开始呢,其实我们采用bfs我们可以把所有的点都先入队列
        for (int i = 0; i < n; i++) {
            q.push({ i,1 << i,0 });
            vis[i][1 << i];
        }
        while (q.size()) {
            auto [u,now,step] = q.front(); q.pop();
            if (now == ((1 << n) - 1)) return step;
            for (auto v : graph[u]) {
                int a = (1 << v) | now;
                if (vis[v][a]) continue;  // 注意这个是v
                vis[v][a] = 1;
                q.push({ v,a,step + 1 });
            }
        }
        return -1;
    }
};

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我会尽力回答你的问题。 要实现遍历带权无向图所有节点最短路径算法,我们可以使用Dijkstra算法。以下是使用C语言实现该算法的步骤: 1. 首先,我们需要定义一个结构体来表示图中的每个节点,其中包括该节点的编号、到起点的最短距离、以及该节点的前驱节点。 ``` struct Node { int id; // 节点编号 int dist; // 到起点的最短距离 int prev; // 前驱节点 }; ``` 2. 然后,我们需要定义一个函数来读取输入的节点个数和邻接矩阵,并且初始化每个节点的信息。 ``` void init(int n, int matrix[][n], struct Node nodes[]) { for (int i = 0; i < n; i++) { nodes[i].id = i; nodes[i].dist = INT_MAX; // 初始距离为无穷大 nodes[i].prev = -1; // 初始前驱节点为-1 } nodes[0].dist = 0; // 起点到起点的距离为0 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (matrix[i][j] != 0) { // 若节点i和节点j有边相连 // 将节点i的邻居节点加入节点i的邻接表中 struct Neighbor *p = (struct Neighbor *) malloc(sizeof(struct Neighbor)); p->id = j; p->weight = matrix[i][j]; p->next = nodes[i].neighbors; nodes[i].neighbors = p; } } } } ``` 3. 接下来,我们需要定义一个函数来找到当前未访问节点中距离起点最近的节点。 ``` int find_min_dist(struct Node nodes[], int n) { int min_dist = INT_MAX; int min_node = -1; for (int i = 0; i < n; i++) { if (nodes[i].dist < min_dist && nodes[i].visited == 0) { min_dist = nodes[i].dist; min_node = i; } } return min_node; } ``` 4. 然后,我们需要定义一个函数来更新当前节点的邻居节点的距离信息。 ``` void update_neighbors(struct Node nodes[], int node_id) { struct Neighbor *p = nodes[node_id].neighbors; while (p != NULL) { int neighbor_id = p->id; int new_dist = nodes[node_id].dist + p->weight; if (new_dist < nodes[neighbor_id].dist) { nodes[neighbor_id].dist = new_dist; nodes[neighbor_id].prev = node_id; } p = p->next; } } ``` 5. 最后,我们可以使用Dijkstra算法来遍历整个图,找到所有节点最短路径。 ``` void dijkstra(int n, int matrix[][n]) { struct Node nodes[n]; init(n, matrix, nodes); int count = 0; while (count < n) { int node_id = find_min_dist(nodes, n); if (node_id == -1) break; nodes[node_id].visited = 1; update_neighbors(nodes, node_id); count++; } for (int i = 0; i < n; i++) { printf("Node %d: dist=%d, prev=%d\n", i, nodes[i].dist, nodes[i].prev); } } ``` 使用以上代码,我们可以输入节点个数和邻接矩阵,然后输出所有节点最短路径
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wniuniu_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值