題意:從S出發,去抓每一個A,求總路徑最短長度。在S點和A點人可以分身成2人,不過一次只能讓一個人走。
思路是先利用BFS求出各點之間的距離,建成圖,再套用最小生成樹模板。
一次性A了。不過覺得在判斷第幾個編號的點時稍顯麻煩了。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int inf=1000000; const int maxn=205; char mapp[maxn][maxn]; bool visit[maxn][maxn]; bool vis[maxn]; int dx[]= {-1,0,1,0}; //四個方向 int dy[]= {0,-1,0,1}; int mat[maxn][maxn],dis[maxn]; int cou,ans; struct Node { int x; int y; int s; //記錄距離 int num; //點的編號 } next,nodes[maxn]; //nodes[]存所有的點 void bfs(Node node,int a) { memset(visit,0,sizeof(visit)); node.s=0; mapp[node.y][node.x]=' '; //訪問過後將'S'或'A'變成' ',下次不需重復訪問 queue<Node>q; visit[node.x][node.y]=true; q.push(node); while(!q.empty()) { node=q.front(); if(mapp[node.y][node.x]=='A') { if(a==0) { nodes[cou]=node; mat[a][cou]=mat[cou][a]=node.s; cou++; //記錄有多少個點 } else { int b; for(int j=0;; j++) if(nodes[j].x==node.x && nodes[j].y==node.y) { b=nodes[j].num; break; } mat[a][b]=mat[b][a]=node.s; //將距離寫入對角矩陣 } } q.pop(); for(int i=0; i<4; i++) { next=node; next.x=node.x+dx[i]; next.y=node.y+dy[i]; if(!visit[next.x][next.y] && (mapp[next.y][next.x]==' ' || mapp[next.y][next.x]=='A')) { visit[next.x][next.y]=true; next.s=node.s+1; q.push(next); } } } return ; } bool prim() { memset(vis,0,sizeof(vis)); for(int i=0;i<cou;i++) dis[i]=(i==0? 0:inf); ans=0; for(int i=0;i<cou;i++) { int temp=inf,k=0; for(int j=0;j<cou;j++) { if(!vis[j] && dis[j]<temp ) { temp=dis[j]; k=j; } } if(temp==inf) return false; vis[k]=true; ans+=temp; for(int j=0;j<cou;j++) { if(!vis[j] && dis[j]>mat[k][j]) dis[j]=mat[k][j]; } } return true; } int main() { //freopen("in.txt","r",stdin); int n; scanf("%d",&n); while(n--) { int x,y; memset(mapp,0,sizeof(mapp)); scanf("%d%d",&x,&y); char c[maxn]={0}; gets(c); for(int i=0; i<y; i++) gets(mapp[i]); for(int i=0; i<x; i++) for(int j=0; j<y; j++) if(mapp[i][j]=='S') { nodes[0].y=i; nodes[0].x=j; } bool flag=true; cou=1; for(int i=0; i<cou; i++) { bfs(nodes[i],i); if(flag) { for(int j=0; j<cou; j++) nodes[j].num=j; //給各個點編號,只運行一次 flag=false; } } prim(); printf("%d\n",ans); } return 0; }