UVa 929 Number Maze( Dijsktra + 优先队列)

本文介绍了一种基于Dijkstra算法的优化实现方法,利用优先队列替代传统的数组结构,有效提高了算法效率。针对大规模数据集(10e6级别)进行路径寻优问题时,通过使用优先队列实现Dijkstra算法的优化,最终达到了预期效果。

这道题是Dij的变体,由于最大的数据一共是10e6的规模,矩阵一定不过

然后看一下变数,假设每个点发出四条边(上,下, 左,右,这里就包括了双向的边了),那么数据规模就是4*10e6,结构体这样大规模,数组应该是承受不了的,如果用vector的话,应该是可以的,但是还是很麻烦

所以,我们就可以利用两个二维数组来代替边表,因为对于每个点,只要遍历它的上下左右即可

数据结构解决了,那么就是算法实现了,开始直接用的dij,无疑超时了,dij的时间复杂度是N*N,那么也就是10e12的规模,所以后来就用的优先队列来优化

这也是我第一次使用优先队列,发现还是很好用的,按照优先级别来进行优先出队

代码如下:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1000;
const int INF = 100000000;
int g[N][N], cost[N][N];
int T, r, c;
struct node { 
    int i, j, w; 
    bool operator < ( const struct node a ) const
    {
       return w > a.w;
    } 
}tl;
void dij() {
    int mi, ri, ci;
    bool vis[N][N];
    priority_queue <struct node> pq;
    memset(vis, 0, sizeof(vis));
    g[1][1] = cost[1][1];
    tl.i = tl.j = 1, tl.w = g[1][1];
    pq.push(tl);
    while ( !pq.empty() ) {
        tl = pq.top(); pq.pop(); ri = tl.i, ci = tl.j;
        if ( vis[ri][ci] ) continue;
        vis[ri][ci] = true;
        //printf("%d  %d\n", ri, ci);
        if ( ri > 1 && !vis[ri-1][ci] && g[ri-1][ci] > g[ri][ci] + cost[ri-1][ci] ) {
            g[ri-1][ci] = g[ri][ci] + cost[ri-1][ci];
            tl.i = ri-1, tl.j = ci, tl.w = g[ri-1][ci];
            pq.push(tl);
        }
        if ( ri < r && !vis[ri+1][ci] && g[ri+1][ci] > g[ri][ci] + cost[ri+1][ci] ) {
            g[ri+1][ci] = g[ri][ci] + cost[ri+1][ci];
            tl.i = ri+1, tl.j = ci, tl.w = g[ri+1][ci];
            pq.push(tl);
        }
        if ( ci > 1 && !vis[ri][ci-1] && g[ri][ci-1] > g[ri][ci] + cost[ri][ci-1] ) {
            g[ri][ci-1] = g[ri][ci] + cost[ri][ci-1];
            tl.i = ri, tl.j = ci-1, tl.w = g[ri][ci-1];
            pq.push(tl);
        }
        if ( ci < c && !vis[ri][ci+1] && g[ri][ci+1] > g[ri][ci] + cost[ri][ci+1] ) {
            g[ri][ci+1] = g[ri][ci] + cost[ri][ci+1];
            tl.i = ri, tl.j = ci+1, tl.w = g[ri][ci+1];
            pq.push(tl);
        }
    }
} 
int main()
{
    scanf("%d", &T);
    while ( T-- ) {
        scanf("%d%d", &r, &c);
        for ( int i = 1; i <= r; ++i )
            for ( int j = 1; j <= c; ++j ) scanf("%d", &cost[i][j]), g[i][j] = INF;
        dij();
        printf("%d\n", g[r][c]);
    }
}
 


### C语言实现迷宫求解程序设计方法 以下内容详细介绍了如何使用深度优先搜索(DFS)、栈和队列在C语言中实现迷宫求解。 #### 数据结构与初始化 迷宫通常以二维数组表示,其中0代表可通行路径,1代表障碍物或墙壁。此外,需要定义方向数组来表示上下左右四个移动方向[^3]。 ```c #define MAZE_HEIGHT 10 #define MAZE_WIDTH 10 int maze[MAZE_HEIGHT][MAZE_WIDTH]; bool visited[MAZE_HEIGHT][MAZE_WIDTH]; // 方向数组:上、下、左、右 int dir[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; ``` 初始化迷宫矩阵时,可以随机生成障碍物或手动设定。以下是一个随机生成迷宫的示例: ```c void initializeMaze() { for (int i = 0; i < MAZE_HEIGHT; ++i) { for (int j = 0; j < MAZE_WIDTH; ++j) { maze[i][j] = (rand() % 2) ? 1 : 0; // 随机生成障碍物或路径 visited[i][j] = false; } } // 设定起点和终点 maze[0][0] = 0; // 起点 maze[MAZE_HEIGHT - 1][MAZE_WIDTH - 1] = 0; // 终点 } ``` #### 深度优先搜索(DFS)实现 DFS可以通过递归或栈实现。以下是基于递归的DFS实现[^4]: ```c bool isValid(int x, int y) { return (x >= 0 && x < MAZE_HEIGHT && y >= 0 && y < MAZE_WIDTH && maze[x][y] == 0 && !visited[x][y]); } bool dfs(int x, int y) { if (x == MAZE_HEIGHT - 1 && y == MAZE_WIDTH - 1) { printf("Solution found!\n"); return true; } visited[x][y] = true; for (int i = 0; i < 4; i++) { int newX = x + dir[i][0]; int newY = y + dir[i][1]; if (isValid(newX, newY)) { if (dfs(newX, newY)) { return true; } } } return false; } ``` 如果需要手动实现栈,则可以通过结构体和数组模拟栈操作[^1]: ```c typedef struct { int x, y; } Point; Point stack[MAZE_HEIGHT * MAZE_WIDTH]; int top = -1; void push(Point p) { stack[++top] = p; } Point pop() { return stack[top--]; } bool isEmpty() { return top == -1; } bool dfsStack(int startX, int startY) { Point current = {startX, startY}; push(current); while (!isEmpty()) { current = pop(); if (current.x == MAZE_HEIGHT - 1 && current.y == MAZE_WIDTH - 1) { printf("Solution found!\n"); return true; } if (!visited[current.x][current.y]) { visited[current.x][current.y] = true; for (int i = 0; i < 4; i++) { int newX = current.x + dir[i][0]; int newY = current.y + dir[i][1]; if (isValid(newX, newY)) { Point next = {newX, newY}; push(next); } } } } return false; } ``` #### 广度优先搜索(BFS)实现 BFS通过队列实现,能够找到最短路径。以下是基于队列的BFS实现[^2]: ```c typedef struct { int x, y, step; } Node; Node queue[MAZE_HEIGHT * MAZE_WIDTH]; int front = 0, rear = 0; void enqueue(Node n) { queue[rear++] = n; } Node dequeue() { return queue[front++]; } bool isQueueEmpty() { return front == rear; } int bfs(int startX, int startY) { Node start = {startX, startY, 0}; enqueue(start); visited[startX][startY] = true; while (!isQueueEmpty()) { Node current = dequeue(); if (current.x == MAZE_HEIGHT - 1 && current.y == MAZE_WIDTH - 1) { printf("Shortest path: %d steps\n", current.step); return current.step; } for (int i = 0; i < 4; i++) { int newX = current.x + dir[i][0]; int newY = current.y + dir[i][1]; if (isValid(newX, newY)) { visited[newX][newY] = true; Node next = {newX, newY, current.step + 1}; enqueue(next); } } } return -1; } ``` #### 总结 上述代码展示了如何使用DFS和BFS解决迷宫问题。DFS适合寻找任意一条路径,而BFS能够找到最短路径。通过栈和队列的数据结构支持,可以灵活地实现这两种算法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值