FZU 2186 BFS + shape pressure shortest Circuit
At first, there were only 10 treasures, with a matrix of 100*100,
Decisive write pressure BFS, and then decisive timeout ..
Positive Solution: do not consider the treasure first, do BFS calculation first, the shortest path between each treasure (including the starting point), and then the shortest path.
Note the third case: the starting point is negative. There is no treasure. There is a treasure and the treasure is at the origin.
#include "stdio.h"#include "string.h"#include "algorithm"#include "queue"using namespace std;const int inf=0x3f3f3f3f;struct Mark{ int x,y;}mark[15];struct node{ int x,y,t;};int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} };int b[15];int str[110][110];int dis[15][15];int n,m,cnt;int used[110][110];int dp[5010][15];int Min(int a,int b){ if (a
q; node cur,next; int i; memset(used,0,sizeof(used)); cur.x=mark[w].x; cur.y=mark[w].y; cur.t=0; q.push(cur); used[mark[w].x][mark[w].y]=1; while (!q.empty()) { cur=q.front(); q.pop(); for (i=0;i<4;i++) { next.x=cur.x+dir[i][0]; next.y=cur.y+dir[i][1]; if (next.x<0 || next.y<0 || next.x>=n || next.y>=m) continue; if (str[next.x][next.y]<0) continue; if (used[next.x][next.y]==0) { used[next.x][next.y]=1; next.t=cur.t+1; if (str[next.x][next.y]>0) { dis[w][str[next.x][next.y]]=Min(dis[w][str[next.x][next.y]],next.t); dis[str[next.x][next.y]][w]=dis[w][str[next.x][next.y]]; } q.push(next); } } }}int main(){ int i,j,ans,flag,aim,l; b[0]=1; for (i=1;i<=12;i++) b[i]=b[i-1]*2; while (scanf("%d%d",&n,&m)!=EOF) { cnt=0; for (i=0;i
0 && i+j!=0) { mark[++cnt].x=i; mark[cnt].y=j; str[i][j]=cnt; } } if (cnt==0) { printf("0\n"); continue; } if (cnt==1 && str[0][0]>0) { printf("0\n"); continue; } if (str[0][0]<0) { printf("-1\n"); continue; } mark[0].x=0; mark[0].y=0; memset(dis,inf,sizeof(dis)); for (i=0;i<=cnt;i++) bfs(i); flag=1; for (i=1;i<=cnt;i++) if (dis[0][i]==inf) { printf("-1\n"); flag=0; } if (flag==0) continue; memset(dp,inf,sizeof(dp)); dp[1][0]=0; aim=b[cnt+1]-1; for (l=0;l<=aim;l++) for (i=0;i<=cnt;i++) for (j=0;j<=cnt;j++) if (i!=j) { if ((b[i]&l)==0) continue; if ((b[j]&l)!=0) continue; if (dp[l][i]==inf) continue; dp[l|b[j]][j]=Min(dp[l|b[j]][j],dp[l][i]+dis[i][j]); } ans=inf; for (i=1;i<=cnt;i++) ans=Min(ans,dp[aim][i]+dis[i][0]); printf("%d\n",ans); } return 0;}