poj 3026 Borg Maze

题目大意:s会分裂,然后从s到A的最小的步是多少。

解题思路:先bfs算出A或者S到任何点的距离,然后最求最小生成树,用dij或者prim都可以



#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 100+10;
char mp[maxn][maxn];
int cost[maxn][maxn];
int a[maxn][maxn];
int T[maxn][maxn];
int d[4][2]={0,1,0,-1,1,0,-1,0};
struct Point{
    int x,y;
    Point(){};
    Point(int zz,int yy){
        x=zz;
        y=yy;
    }
};
struct Node{
    int u,v;
    int cost;
}node[maxn*maxn];
bool cmd(Node a,Node b){
    return a.cost<b.cost;
}
int pa[maxn];
int find(int x){
    if(pa[x]==x) return x;
    else return pa[x]=find(pa[x]);
}
void join(int x,int y){
    int root=find(x);
    int root1=find(y);
    if(root!=root1){
        pa[root1]=root;
    }
}
bool same(int x,int y){
    return find(x)==find(y);
}
void bfs(int x,int y){
    memset(T,-1,sizeof(T));
    queue<Point> q;
    while(!q.empty()) q.pop();
    q.push(Point(x,y));
    T[x][y]=0;
    while(!q.empty()){
        Point p;
        p=q.front();
        q.pop();
        if(a[p.x][p.y]!=-1){
            cost[a[x][y]][a[p.x][p.y]]=T[p.x][p.y];
        }
        for(int i=0;i<4;i++){
            int dx=p.x+d[i][0];
            int dy=p.y+d[i][1];
            if(mp[dx][dy]=='#' || T[dx][dy]!=-1) continue;
            T[dx][dy]=T[p.x][p.y]+1;
            q.push(Point(dx,dy));
        }
    }
}




int dij(int tot){
    for(int i=0;i<=tot;i++) pa[i]=i;
        int c=0;
        for(int i=0;i<tot;i++){
            for(int j=0;j<i;j++){
                if(cost[i][j]>0){
                    node[c].u=i;
                    node[c].v=j;
                    node[c++].cost=cost[i][j];
                }
            }
        }
        sort(node,node+c,cmd);

        int sum=0;
        for(int i=0;i<c;i++){
            int u=node[i].u;
            int v=node[i].v;
            if(!same(u,v)){
                sum+=node[i].cost;
                join(u,v);
            }
        }
        return sum;

}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        gets(mp[0]);
        memset(a,-1,sizeof(a));
        memset(cost,0,sizeof(cost));
        int tot=0;
        for(int i=0;i<m;i++){
            gets(mp[i]);
            for(int j=0;j<n;j++){
                if(mp[i][j]=='A' ||mp[i][j]=='S'){
                    a[i][j]=tot++;
                }
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<m;j++){
                if(a[i][j]!=-1){
                    bfs(i,j);
                }
            }
        }

        int sum=dij(tot);
        printf("%d\n",sum);
    }
    return 0;
}



这个题输入的数据应该有坑。。。。坑了我几个小时,

gets(mp[0]);这样存缓冲就可以过

而getchar()就不能过。。。。。。。有毒啊






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值