解题:USACO13JAN Island Travels

题面

好像没啥可说的,就当练码力了......

先用BFS跑出岛屿,然后跑最短路求岛屿间的距离,最后状压DP得出答案

注意细节,码码码2333

  1 #include<set>
  2 #include<queue> 
  3 #include<cstdio>
  4 #include<cstring>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=16,M=256,L=55;
  8 const int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
  9 struct a
 10 {
 11     int xx,yy;
 12 }que[L*L];
 13 char mapp[L][L];
 14 int val[N][N],dp[1<<N][N];
 15 int Mapp[L][L],vis[L][L],dis[L][L];
 16 int n,m,f,b,nx,ny,land,shal,nde,all,ans=2e9;
 17 deque<a> qs;
 18 bool ok1(int x,int y)
 19 {
 20     return mapp[x][y]=='X'&&!Mapp[x][y]&&x>=1&&x<=n&&y>=1&&y<=m;
 21 }
 22 void BFS1(int x,int y)
 23 {
 24     que[f=b=0]=(a){x,y},Mapp[x][y]=++land;
 25     while(f<=b)
 26     {
 27         a tn=que[f++];
 28         int tx=tn.xx,ty=tn.yy;
 29         for(int i=0;i<4;i++)
 30              if(ok1(nx=tx+mov[i][0],ny=ty+mov[i][1]))
 31                  Mapp[nx][ny]=land,que[++b]=(a){nx,ny};
 32     }
 33 }
 34 bool ok2(int x,int y)
 35 {
 36     return mapp[x][y]=='S'&&!Mapp[x][y]&&x>=1&&x<=n&&y>=1&&y<=m;
 37 }
 38 void BFS2(int x,int y)
 39 {
 40     que[f=b=0]=(a){x,y},Mapp[x][y]=--shal;
 41     while(f<=b)
 42     {
 43         a tn=que[f++];
 44         int tx=tn.xx,ty=tn.yy;
 45         for(int i=0;i<4;i++)
 46              if(ok2(nx=tx+mov[i][0],ny=ty+mov[i][1]))
 47                  Mapp[nx][ny]=shal,que[++b]=(a){nx,ny};
 48     }
 49 }
 50 bool ok(int x,int y)
 51 {
 52     return Mapp[x][y]&&!vis[x][y]&&x>=1&&x<=n&&y>=1&&y<=m;
 53 }
 54 void BFS(int x,int y)
 55 {
 56     qs.push_back((a){x,y});
 57     memset(vis,0,sizeof vis);
 58     memset(dis,0,sizeof dis);
 59     nde=Mapp[x][y],val[nde][nde]=0,vis[x][y]=true;
 60     while(!qs.empty())
 61     {
 62         a tt=qs.front(); qs.pop_front(); int tx=tt.xx,ty=tt.yy; 
 63         for(int i=0;i<4;i++)
 64             if(ok(nx=tx+mov[i][0],ny=ty+mov[i][1]))
 65             {
 66                 vis[nx][ny]=true;
 67                 if(Mapp[tx][ty]<0) dis[nx][ny]=dis[tx][ty]+1,qs.push_back((a){nx,ny});
 68                 else if(Mapp[tx][ty]>0) dis[nx][ny]=dis[tx][ty],qs.push_front((a){nx,ny});
 69             }
 70     }
 71     for(int i=1;i<=n;i++)
 72         for(int j=1;j<=m;j++)
 73             if(Mapp[i][j]>0) 
 74                 val[nde][Mapp[i][j]]=min(val[nde][Mapp[i][j]],dis[i][j]);
 75 }
 76 int ins(int nde)
 77 {
 78     return 1<<(nde-1);
 79 }
 80 int main ()
 81 {
 82     scanf("%d%d",&n,&m);
 83     for(int i=1;i<=n;i++)
 84         scanf("%s",mapp[i]+1);
 85     for(int i=1;i<=n;i++)
 86         for(int j=1;j<=m;j++)    
 87             if(ok1(i,j)) BFS1(i,j);
 88             else if(ok2(i,j)) BFS2(i,j);
 89     memset(val,0x3f,sizeof val);
 90     for(int i=1;i<=n;i++)
 91         for(int j=1;j<=m;j++)
 92             if(Mapp[i][j]>0) BFS(i,j);
 93     all=(1<<land)-1; 
 94     memset(dp,0x3f,sizeof dp);
 95     for(int i=1;i<=land;i++) dp[ins(i)][i]=0;
 96     for(int i=0;i<=all;i++)
 97         for(int j=1;j<=land;j++)    
 98             if(i&ins(j))
 99                 for(int k=1;k<=land;k++)
100                     if(!(i&ins(k))&&j!=k)
101                         dp[i|ins(k)][k]=min(dp[i|ins(k)][k],dp[i][j]+val[j][k]);
102     for(int i=1;i<=land;i++) ans=min(ans,dp[all][i]);
103     printf("%d",ans);
104     return 0;
105 }
View Code

猜你喜欢

转载自www.cnblogs.com/ydnhaha/p/9780150.html
今日推荐