# FZU 2186 小明的迷宫 【压状dp】

## Sample Input

3 3 0 0 0 0 100 0 0 0 0 2 2 1 1 1 1

## Sample Output

4 4

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 using namespace std;
6 const int dx[10]={0,0,0,1,-1},dy[10]={0,1,-1,0,0};
7 int a[109][109],monx[100],mony[100],n,m,ma[109][109];
8 queue<int>qans,qx,qy;
9 bool visit[109][109];
10 int check(int x,int y){
11     if(x<=0 || x>n || y<=0 || y>m || a[x][y]<0 || visit[x][y])return 1;
12     return 0;
13 }
14 void bfs(int x,int y,int sc)
15 {
16     memset(visit,0,sizeof(visit));
17     int l=0,r=0;visit[x][y]=1;
18     qx.push(x);qy.push(y);qans.push(0);
19     while(!qx.empty())
20     {
21         x=qx.front();y=qy.front();
22         qx.pop();qy.pop();
23         int ans=qans.front();
24         qans.pop();
25         for(int i=1;i<=4;i++)
26         {
27             int xx=x+dx[i],yy=y+dy[i];
28             if(check(xx,yy))continue;
29             if(a[xx][yy]>0)ma[sc][a[xx][yy]]=ans+1;
30             visit[xx][yy]=1;
31             qx.push(xx);qy.push(yy);qans.push(ans+1);
32         }
33     }
34 }
35 int only_one(int k){
36         if(k-(k & (-k)) == 0)return 1;return 0;
37 }
38 int dp[15][10000];
39 int dfs2(int k,int s,int h)
40 {
41         if(dp[k][s]!=-1)return dp[k][s];
42         if(only_one(s))return ma[k][1];
43         int ans=0x3f3f3f3f,full = ((1<<(h))-1) ^ (1<<(k-1));
44         for(int i=1;i<=h;i++)
45         if(i != k && ((s & ((1<<(i-1)))) !=0))ans=min(ans,dfs2(i,s & full,h) + ma[k][i]);
46         return dp[k][s]=ans;
47 }
48 int main()
49 {
50     while(scanf("%d%d",&n,&m)!=EOF)
51     {
52                 memset(dp,-1,sizeof(dp));
53                 memset(ma,0x3f,sizeof(ma));
54         int h=0,flag=0;
55         for(int i=1;i<=n;i++)
56         {
57             for(int j=1;j<=m;j++)
58             {
59                 scanf("%d",&a[i][j]);
60                 if(i==1 && j==1)flag=a[i][j];
61                 if(a[i][j]>0 || (i==1 && j==1))a[i][j]=++h,monx[h]=i,mony[h]=j;
62             }
63         }
64         for(int i=1;i<=h;i++)ma[i][i]=0;
65         for(int i=1;i<=h;i++)bfs(monx[i],mony[i],i);
66         if(flag<0)
67         {
68                         printf("-1\n");continue;
69         }
70         int u=dfs2(1,(1<<h)-1,h);
71         if(u>=0x3f3f3f3f)u=-1;
72                 printf("%d\n",u);
73     }
74     return 0;
75 }

posted @ 2015-03-22 16:10  philippica  阅读(389)  评论(0编辑  收藏  举报