poj3026 bfs+prim

来源:互联网 发布:微信隐私保护指引知乎 编辑:程序博客网 时间:2024/06/06 00:05

题意:

有一个n*m的图,有S,A,#和空格,S可以到达A并且使A变成S,然后这个S又可以去侵染别的A,问A都变成S需要多少步?

分析:

题目相当于求出S和A构成的最小生成树。首先把S和A找出来,枚举每个S和A,然后bfs求一下单点到其他点的最短距离,然后套prim模板就行。

这题有个特别坑的地方就是数字后面可等有多个空格,好坑!!!

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<stack>#include<map>#include<vector>#include<queue>using namespace std;#define mp make_pairconst int INF=1000000000;const int N=500+9;typedef pair<int,int>pii; //点的坐标 <x,y>typedef pair<int,pii>piii; //<步数,点>int w[N][N],low[N];bool vis[N][N];char s[N][N];int n,m;int dx[4][2]={{-1,0},{1,0},{0,-1},{0,1}};vector<pii>vec; //存S和Amap<pii,int>id; //给每个S和A编一个号int sid;void bfs(pii start){    queue<piii>q;    memset(vis,0,sizeof(vis));    q.push(mp(0,start));    vis[start.first][start.second]=1;    while(!q.empty()){        piii p=q.front();q.pop();        int step=p.first,x=p.second.first,y=p.second.second;        for(int i=0;i<4;i++){            int xx=x+dx[i][0],yy=y+dx[i][1];            if(xx<0||yy<0||xx==n||yy==m||vis[xx][yy])continue;            vis[xx][yy]=1;            if(s[xx][yy]=='A'||s[xx][yy]=='S'){                w[id[mp(xx,yy)]][sid]=step+1;continue;            }            if(s[xx][yy]==' ')q.push(mp(step+1,mp(xx,yy)));        }    }}int prim(int n){    bool vis[111];    memset(vis,0,sizeof(vis));    vis[0]=1;    int ans=0,p=0;    for(int i=0;i<n;i++)low[i]=w[p][i];    for(int i=1;i<n;i++){        int minn=INF;        for(int j=0;j<n;j++)if(!vis[j]&&minn>low[j])minn=low[p=j];        ans+=minn;        vis[p]=1;        for(int j=0;j<n;j++)if(!vis[j]&&low[j]>w[p][j])low[j]=w[p][j];    }    return ans;}int main(){    int T;scanf("%d",&T);    while(T--){        scanf("%d%d",&m,&n);        vec.clear();        id.clear();        gets(s[0]); //注意可能有多个空格        for(int i=0;i<n;i++){            gets(s[i]);            for(int j=0;j<m;j++)                if(s[i][j]=='A'||s[i][j]=='S')id[mp(i,j)]=vec.size(),vec.push_back(mp(i,j));        }          for(int i=0;i<vec.size();i++)for(int j=0;j<vec.size();j++)w[i][j]=i==j?0:INF;        for(int i=0;i<vec.size();i++){            sid=id[vec[i]];            bfs(vec[i]);        }        printf("%d\n",prim(vec.size()));    }    return 0;}


0 0
原创粉丝点击