hdu 4856 Tunnels

http://acm.hdu.edu.cn/showproblem.php?pid=4856

这道题就是搜索BFS+状压dp,把所经过的隧道的状态用二进制表示,然后dp就行。bfs求出每两个隧道的最短距离。

  1 #include <cstdio>

  2 #include <queue>

  3 #include <cstring>

  4 #include <algorithm>

  5 #define maxn 1000

  6 using namespace std;

  7 const int inf=1<<29;

  8 

  9 int n,m;

 10 char g[16][16];

 11 int gg[16][16];

 12 struct node

 13 {

 14     int x1,y1,x2,y2;

 15 } p[maxn],st3;

 16 int dis[16][16];

 17 int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};

 18 int dp[1<<16][16];

 19 bool vis[maxn][maxn];

 20 

 21 int bfs(int s,int t)

 22 {

 23     queue<node>q;

 24     memset(vis,false,sizeof(vis));

 25     for(int i=0; i<n; i++)

 26     {

 27         for(int j=0; j<n; j++)

 28         {

 29             dis[i][j]=inf;

 30         }

 31     }

 32     node st;

 33     st.x1=p[s].x2;

 34     st.y1=p[s].y2;

 35     dis[p[s].x2][p[s].y2]=0;

 36     vis[p[s].x2][p[s].y2]=true;

 37     q.push(st);

 38     while(!q.empty())

 39     {

 40         node st1=q.front();

 41         q.pop();

 42         if(st1.x1==p[t].x1&&st1.y1==p[t].y1)

 43         {

 44             return dis[p[t].x1][p[t].y1];

 45         }

 46         for(int i=0; i<4; i++)

 47         {

 48             int xx=st1.x1+dir[i][0];

 49             int yy=st1.y1+dir[i][1];

 50             if(xx>=0&&xx<n&&yy>=0&&yy<n&&g[xx][yy]!='#')

 51             {

 52                 if(!vis[xx][yy])

 53                 {

 54                     dis[xx][yy]=dis[st1.x1][st1.y1]+1;

 55                     st3.x1=xx;

 56                     st3.y1=yy;

 57                     vis[xx][yy]=true;

 58                     q.push(st3);

 59                 }

 60             }

 61         }

 62     }

 63     return -1;

 64 }

 65 

 66 int main()

 67 {

 68     while(scanf("%d%d",&n,&m)!=EOF)

 69     {

 70         memset(g,0,sizeof(g));

 71         for(int i=0; i<n; i++)

 72         {

 73             scanf("%s",g[i]);

 74         }

 75         for(int i=0; i<m; i++)

 76         {

 77             scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);

 78             p[i].x1-=1;

 79             p[i].y1-=1;

 80             p[i].x2-=1;

 81             p[i].y2-=1;

 82         }

 83         memset(dp,-1,sizeof(dp));

 84         for(int i=0; i<m; i++)

 85         {

 86             for(int j=0; j<m; j++)

 87             {

 88                 if(i==j) gg[i][j]=0;

 89                 else

 90                 gg[i][j]=bfs(i,j);

 91             }

 92         }

 93         for(int i=0; i<m; i++)

 94         {

 95             dp[1<<i][i]=0;

 96         }

 97         for(int i=0; i<(1<<m); i++)

 98         {

 99             for(int j=0; j<m; j++)

100             {

101                 if((i&(1<<j))==0) continue;

102                 if(dp[i][j]==-1)  continue;

103                 for(int k=0; k<m; k++)

104                 {

105                     if(gg[j][k]==-1) continue;

106                     if(i&(1<<k)) continue;

107                     if(dp[i|(1<<k)][k]==-1) dp[i|(1<<k)][k]=dp[i][j]+gg[j][k];

108                     else dp[i|(1<<k)][k]=min(dp[i|(1<<k)][k],dp[i][j]+gg[j][k]);

109                 }

110             }

111         }

112         int ans=inf;

113         for(int i=0; i<m; i++)

114         {

115             if(dp[(1<<m)-1][i]!=-1)

116             ans=min(ans,dp[(1<<m)-1][i]);

117         }

118         if(ans==inf) printf("-1\n");

119         else

120         printf("%d\n",ans);

121     }

122     return 0;

123 }
View Code

 

你可能感兴趣的:(HDU)