题目如题。题解如题。
因为目标点最多仅仅有4个,先bfs出俩俩最短路(包含起点)。再dfs最短路。)0s1A;(当年弱跪杭州之题,现看如此简单)
#include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct point { int x,y; int cnt; }; char a[105][105]; vector<point>po; int n,m;int k; int mindis[10][10]; int vis[105][105]; int f[4][2]={0,1,0,-1,1,0,-1,0}; int bfs(int s,int t) { memset(vis,0,sizeof(vis)); queue<point>q; po[s].cnt=0; po[t].cnt=-1; q.push(po[s]); vis[po[s].x][po[s].y]=1; while(!q.empty()) { point cur=q.front(); q.pop(); point next; for(int i=0;i<4;i++) { next.x=cur.x+f[i][0]; next.y=cur.y+f[i][1]; if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m&&vis[next.x][next.y]==0&&a[next.x][next.y]!=‘#‘) { next.cnt=cur.cnt+1; if(next.x==po[t].x&&next.y==po[t].y) { return next.cnt; } q.push(next); vis[next.x][next.y]=1; } } } return -1; } int mins=100000000; int vis2[10]; void dfs(int u,int lev,int sumdis) { if(sumdis>=mins)return ; if(lev==k) { if(sumdis<mins) { mins=sumdis;return ; } } for(int i=1;i<=k;i++) { if(!vis2[i]) { vis2[i]=1; dfs(i,lev+1,sumdis+mindis[u][i]); vis2[i]=0; } } } int main() { while(~scanf("%d%d",&n,&m)&&(n||m)) { memset(mindis,0,sizeof(mindis)); mins=100000000; po.clear(); for(int i=0;i<n;i++) { getchar(); for(int j=0;j<m;j++) { scanf("%c",&a[i][j]); if(a[i][j]==‘@‘) { point txy;txy.x=i;txy.y=j; po.push_back(txy); } } } scanf("%d",&k); int aa,bb; for(int i=0;i<k;i++) { scanf("%d%d",&aa,&bb); point txy;txy.x=aa-1;txy.y=bb-1; po.push_back(txy); } int mark=1; for(int i=0;i<k+1;i++) for(int j=i+1;j<k+1;j++) { mindis[j][i]=mindis[i][j]=bfs(i,j); if(mindis[i][j]==-1) { mark=0;break; } } if(mark==0) { printf("-1\n");continue; } memset(vis2,0,sizeof(vis2)); dfs(0,0,0); printf("%d\n",mins); } }
时间: 2024-10-14 05:12:51