Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10424 | Accepted: 3459 |
Description
Input
Output
Sample Input
2 6 5 ##### #A#A## # # A# #S ## ##### 7 7 ##### #AAA### # A# # S ### # # #AAA### #####
Sample Output
8 11
题目大意就是,将所有的S或者A点连起来的最小距离。
这题不得不吐槽,太坑。。。。 我TLE了一天最后是标记没有用BOOL,并且吃字符用getchar()RE,只能用gets(Map[0]);
思路: 将途中S与A用a[][]记录下位置,a[][]保存的值是从1--(S+A的数量 )=n,然后轮流以n个点作为顶点进行收索。构造与其他点间的距离,然后存在mt[][]中。
到其他点的距离实现的方法是用f.ans来记录。最后prim一下。
#include<iostream> #include<cstring> #include<cstdio> #include<queue> #define inf 0x3f3f3f3f using namespace std; struct node { int x,y,ans; }; char Map[2000][2000]; int n,m; int a[2000][2000],point,mt[2000][2000],dis[2000]; int cx[]= {0,0,-1,1},cy[]= {1,-1,0,0},ans; bool vis[2000][2000],bj[2000];//血的教训,以后什么标记都用bool!!! void BFS(int xx,int yy) { memset(vis,0,sizeof(vis)); queue<node >q; node o,f; o.x=xx; o.y=yy; o.ans=0; q.push(o); vis[xx][yy]=1; while(!q.empty()) { o=q.front(); q.pop(); if(a[o.x][o.y]!=0) mt[a[xx][yy]][a[o.x][o.y] ]=o.ans; for(int i=0; i<4; i++) { f=o; f.x+=cx[i]; f.y+=cy[i]; if(f.x>=0&&f.x<m&&f.y>=0&&f.y<n&&!vis[f.x][f.y]&&Map[f.x][f.y]!='#') { vis[f.x][f.y]=1; f.ans++; q.push(f); } } } } void prim() { ans=0; int i,j,pos,MAX; for(i=1; i<=point; i++) dis[i]=mt[1][i]; dis[1]=0; memset(bj,0,sizeof(bj)); bj[1]=1; for(i=1; i<point; i++) { MAX=inf; for(j=1; j<=point; j++) { if(MAX>dis[j]&&!bj[j]) { MAX=dis[j]; pos=j; } } ans+=MAX; bj[pos]=1; for(j=1; j<=point; j++) { if(dis[j]>mt[pos][j]&&!bj[j]) { dis[j]=mt[pos][j]; } } } printf("%d\n",ans); } int main() { int i,j,k,cla; ios::sync_with_stdio(false); scanf("%d",&cla); while(cla--) { scanf("%d%d",&n,&m); point=0; memset(a,0,sizeof(a)); gets(Map[0]); for(int i=0; i<m; i++) { gets(Map[i]); for(int j=0; j<n; j++) { if(Map[i][j] == 'S' || Map[i][j] == 'A') { a[i][j] = ++point; } } } for(i=0; i<m; i++) { for(j=0; j<n; j++) { if(a[i][j]!=0) { BFS(i,j); } } } prim(); } return 0; }