zoukankan      html  css  js  c++  java
  • Borg Maze POJ 3026(BFS+最小生成树)

    http://acm.hust.edu.cn/vjudge/contest/121380#problem/I

    题意:求有字母的各个点都彼此连接起来的最短步数。

    分析:一看到题就想到BFS+最小生成树了, 可是我一开始不知道怎么表示,也没看穿题(还是渣渣啊。。)

    **************************************************************************************************************************************

    根据题意的“分离”规则,重复走过的路不再计算

    因此当使用prim算法求L的长度时,根据算法的特征恰好不用考虑这个问题(源点合并很好地解决了这个问题),L就是最少生成树的总权值W

     

    由于使用prim算法求在最小生成树,因此无论哪个点做起点都是一样的,(通常选取第一个点),因此起点不是S也没有关系

    所以所有的A和S都可以一视同仁,看成一模一样的顶点就可以了

    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int maxn = 105;
    const int oo = 0xfffffff;
    
    int  dir[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
    char maps[maxn][maxn];
    int v[maxn][maxn], dist[maxn], a[maxn][maxn], p[maxn][maxn], vis[maxn];
    int n, m;
    
    struct node
    {
        int x, y, step;
    };
    
    void BFS(int u, int x, int y)
    {
        memset(v, 0, sizeof(v));
    
        node begins, now, next;
        begins.x = x;
        begins.y = y;
        begins.step = 0;
    
        queue<node>Q;
        Q.push(begins);
        v[x][y] = 1;
    
        while(Q.size())
        {
            now = Q.front();
            Q.pop();
    
            if(maps[now.x][now.y]>='A' && maps[now.x][now.y] <='Z')
                p[u][a[now.x][now.y]] = now.step;
    
            for(int i=0; i<4; i++)
            {
                next.x = now.x + dir[i][0];
                next.y = now.y + dir[i][1];
    
                if(next.x>0 && next.x<=m && next.y>0 && next.y<=n && maps[next.x][next.y]!='#' && !v[next.x][next.y])
                {
                    v[next.x][next.y] = 1;
                    next.step = now.step + 1;
                    Q.push(next);
                }
            }
        }
    
    }
    
    void Prim(int k)
    {
        memset(vis, 0, sizeof(vis));
    
        int sum = 0;
    
        for(int i=1; i<=k; i++)
            dist[i] = p[1][i];
    
            vis[1] = 1;
    
        for(int i=1; i<k; i++)
        {
            int index = -1;
            int mins = oo;
    
            for(int j=1; j<=k; j++)
            {
                if(!vis[j] && dist[j]<mins)
                {
                    mins = dist[j];
                    index = j;
                }
            }
    
            sum += mins;
            vis[index] = 1;
    
            for(int j=1; j<=k; j++)
            {
                if(!vis[j] && dist[j] > p[index][j])
                    dist[j] = p[index][j];
            }
        }
    
        printf("%d
    ", sum);
    }
    
    
    int main()
    {
        int T;
    
        scanf("%d", &T);
    
        while(T --)
        {
            int k = 1;
    
            scanf("%d %d ", &n, &m);
    
            for(int i=1; i<=m; i++)
            {
                gets(maps[i]);
                for(int j=1; j<=n; j++)
                {
    
                    if(maps[i][j]=='A' || maps[i][j]=='S')
                        a[i][j] = k++;
    
                }
            }
    
            for(int i=1; i<=m; i++)
            {
                for(int j=1; j<=n; j++)
                    if(i == j) p[i][j] = 0;
                    else p[i][j] = oo;
            }
    
            for(int i=1; i<=m; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    if(maps[i][j]>='A' && maps[i][j] <='Z')
                        BFS(a[i][j], i, j);
                }
            }
    
            Prim(k-1);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    oracle 锁表查看与解锁
    oracle 监视索引是否使用
    oracle 查看数据库版本
    mybatis 中文做参数报错
    windows mysql绿色版配置
    maven使用本地jar包
    Java 使用Jedis连接Redis数据库(-)
    Linux 安装redis
    ELK之在CentOS7.5上使用rpm包安装配置ELK7版本
    Ubuntu-18.04更改安装源为国内源
  • 原文地址:https://www.cnblogs.com/daydayupacm/p/5708096.html
Copyright © 2011-2022 走看看