准备机试Day1-01 bfs+最小生成树 poj3026

题意: 在一个y行,x列的迷宫中,有可行走的通路空格‘ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。

先bfs求两两字母间最短路,作为图的边

然后用prim算法求图的最小生成树
prim算法(摘自百度百科):

算法描述

编辑
1).输入:一个加权连通图,其中顶点集合为V,边集合为E;
2).初始化:V new = {x},其中x为集合V中的任一节点(起始点),E new = {},为空;
3).重复下列操作,直到V new = V:
a.在集合E中选取权值最小的边<u, v>,其中u为集合V new中的元素,而v不在V new 集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
b.将v加入集合V new中,将<u, v>边加入集合E new中;
4).输出:使用集合V new和E new来描述所得到的 最小生成树
代码:
#include<iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int R,C;
char grid[1000][1000];
int tag[1000][1000];
bool vis[1000][1000];
int len[1000][1000];
int mov[4][2] = {{1,0},{0,-1},{-1,0},{0,1}};
bool is_in[5000];
char temp[510];

struct node{
    int r,c;
    int step;
}s[5000];

void bfs(int u){
    node t1,t2;
    queue<node> q;
    t1.r = s[u].r;
    t1.c = s[u].c;
    t1.step = 0;
    vis[t1.r][t1.c] = true;
    q.push(t1);
    while(!q.empty()){
        t1 = q.front();
        q.pop();
        int v = tag[t1.r][t1.c];
        if(v!=-1){
            len[u][v] = len[v][u] = t1.step;
        }
        for(int i=0;i<4;i++){
            t2.r = t1.r + mov[i][0];
            t2.c = t1.c + mov[i][1];
            if(t2.r<R && t2.r>=0 && t2.c<C && t2.c>=0){
                if(vis[t2.r][t2.c]==false && grid[t2.r][t2.c]!='#'){
                    vis[t2.r][t2.c] = true;
                    t2.step = t1.step + 1;
                    q.push(t2);
                }
            }
        }
    }

}

int main(){
    int T,i,j,k;
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&C,&R);
        memset(tag,-1,sizeof(tag));
        memset(len,-1,sizeof(len));
        gets(temp);
        for(i=0;i<R;i++){

            gets(grid[i]);
        }
        k=1;
        for(i=0;i<R;i++){
            for(j=0;j<C;j++){
                if(grid[i][j]=='S' || grid[i][j]=='A'){
                    s[k].r = i;
                    s[k].c = j;
                    tag[i][j]=k++;
                }
            }
        }

        for(i=1;i<k;i++){
            memset(vis,false,sizeof(vis));
            bfs(i);
        }

        memset(is_in,false,sizeof(is_in));
        is_in[1] = true;


        int ans = 0;
        //求最小生成树
        while(true){

            int t = 1000000000;
            int pos = -1;

            for(i=1;i<k;i++){
                if(is_in[i]){

                    for(j=1;j<k;j++){
                        //if(j == i) continue;
                        if(!is_in[j]){
                            if(t>len[i][j]){
                                t = len[i][j];
                                pos = j;
                            }
                        }
                    }

                }
            }

            if(pos == -1) break;
            is_in[pos] = true;
            ans += t;

        }
        printf("%d\n",ans);


    }
    return 0;

}
wa了两次..之前用getchar()吃掉输入整数后面的换行不知道为啥wa..看disscus改成gets一个字符串就过了,是测试数据里有空格..然后数组改大就能过。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值