poj3026

来源:互联网 发布:国内高薪职业 知乎 编辑:程序博客网 时间:2024/06/05 17:55

题目链接:http://poj.org/problem?id=3026

题目大意:给出一个二维字符串,里面有#代表不能走,' '空格代表可以走,然后还有'A'和'S'代表人,问从S到达所有'A'的最小通路,就是最小生成树(意思就是s,a全部联通的总长度, s和a是一样的  没有区别)

解题思路:因为说了上面的A不会超过100个,所以开个102的数组够了,用BFS找出任意两点相距的最小距离保存在图中之后prim就可以了。


这道题需要主要两点:1.输入的是先列的数量 再是行的数量

2.处理输入时需要读取整一行  因为存在空隔  注意下gets()可能会吃掉上一行的换行符

#include <iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<queue>#include<string.h>using namespace std;#define maxn 200#define inf 0x3f3f3f3fint n,m;struct node{int x,y;}a[maxn];int tot;int maps[maxn][maxn];char s[maxn][maxn];bool vis[maxn];int  dis[maxn];void prim(){memset(vis,false,sizeof vis);vis[0]=1;for(int i=1;i<tot;i++)dis[i]=maps[0][i];dis[0]=0;int sum=0;for(int i=0;i<tot;i++){int pos=-1;for(int j=0;j<tot;j++){if(!vis[j]&&(pos==-1||dis[j]<dis[pos]))pos=j;}vis[pos]=true;sum+=dis[pos];for(int j=0;j<tot;j++){if(!vis[j]&&dis[j]>maps[pos][j])dis[j]=maps[pos][j];}}printf("%d\n",sum);}bool vist[maxn][maxn];int go[4][2]={1,0,-1,0,0,1,0,-1};int step[maxn][maxn];void bfs(int start){queue<node>q;memset(vist,false,sizeof vist);memset(step,0,sizeof step);node u;u.x=a[start].x;u.y=a[start].y;q.push(u);int x=u.x,y=u.y;vist[u.x][u.y]=true;step[u.x][u.y]=0;while(!q.empty()){u=q.front();q.pop();for(int i=0;i<4;i++){node v=u;v.x+=go[i][0];v.y+=go[i][1];if(!vist[v.x][v.y]&&s[v.x][v.y]!='#'){vist[v.x][v.y]=true;step[v.x][v.y]=step[u.x][u.y]+1;q.push(v);}}}for(int i=0;i<tot;i++){maps[start][i]=step[a[i].x][a[i].y];}}int main(){int t;scanf("%d\n",&t);while(t--){tot=0;gets(s[0]);        sscanf(s[0],"%d%d",&m,&n);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'){a[tot].x=i;a[tot].y=j;tot++;}}}for(int i=0;i<tot;i++)for(int j=0;j<tot;j++)if(i==j)maps[i][j]=0;else maps[i][j]=inf;for(int i=0;i<tot;i++)bfs(i);prim();}return 0;}


原创粉丝点击