题目大意:让你求从S点到A点的所能达到的最小距离。
算法思路:先通过bfs求出各个字母之间的最短距离,再求最小生成树。
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; #define INF 0x3f3f3f3f typedef struct Node { int x,y; int lev; int sym; }; Node nodes[3000]; char a[300][300]; int edges[300][300]; int dist[3000]; int t; int n,m,ssym,num,sum; int dx[4]={-1,0,1,0}; int dy[4]={0,-1,0,1}; bool visited[300][300],visited2[3003]; int xb[300][300]; void bfs(Node node) { memset(visited,false,sizeof(visited)); queue<Node>que; que.push(node); visited[node.x][node.y]=true; while(!que.empty()) { Node cur=que.front(); que.pop(); for(int i=0;i<4;i++) { int nx=cur.x+dx[i]; int ny=cur.y+dy[i]; if(1<=nx&&nx<=n&&1<=ny&&ny<=m&&!visited[nx][ny]&&a[nx][ny]!='#') { if(a[nx][ny]=='A'||a[nx][ny]=='S') { edges[node.sym][nodes[xb[nx][ny]].sym]=cur.lev+1; } Node flag; flag.x=nx; flag.y=ny; flag.lev=cur.lev+1; visited[nx][ny]=true; que.push(flag); } } } } void prim() { sum=0; int i,j; memset(dist,0x3f,sizeof(dist)); memset(visited2,false,sizeof(visited2)); for(i=1;i<num;i++) { dist[i]=edges[1][i]; } visited2[1]=true; for(i=1;i<num;i++) { int MIN=INF,node=-1; for(j=1;j<num;j++) { if(!visited2[j]&&dist[j]<MIN) { MIN=dist[j]; node=j; } } if(node==-1) return; visited2[node]=true; sum+=dist[node]; for(j=1;j<num;j++) { if(!visited2[j]&&dist[j]>edges[node][j]) { dist[j]=edges[node][j]; } } } } int main() { scanf("%d",&t); int i,j; while(t--) { memset(nodes,0,sizeof(nodes)); memset(xb,0,sizeof(xb)); memset(edges,0,sizeof(edges)); num=1; scanf("%d%d",&m,&n); for(i=0;i<=n;i++) { gets(a[i]+1); } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(a[i][j]=='S') { Node node; node.x=i; node.y=j; node.lev=0; ssym=num; node.sym=num; xb[i][j]=num; nodes[num++]=node; } else if(a[i][j]=='A') { Node node; node.x=i; node.y=j; node.lev=0; node.sym=num; xb[i][j]=num; nodes[num++]=node; } } } for(i=1;i<=num;i++) { bfs(nodes[i]); } prim(); printf("%d\n",sum); } }