HZOJ 走格子

作者的正解:

对于100%的数据:行动可以分为两种:

1. 步行,花费一个单位的时间移动到4联通的相邻格子中去.

2. 使用传送门,指定一个方向的墙的前面的一个格子,步行至最近的一个墙的面前,使用传送门传送.花费的时间为到达最近墙面前花费的时间+1.

两种行动相组合即可组成任意行动过程.那BFS求出最近的墙的距离,预处理上下左右的第一面墙前的格子.然后建图用DJ跑最短路即可.复杂度为O(MNlog(NM))。

 其实所的很清楚了,只是不知道bfs是个什么玩意……直接$n^3$暴扫就行了呀。倒真的没什么可说的,看代码吧。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<queue>
  5 #define MP(a,b) make_pair(a,b)
  6 #define ma(x,y) memset(x,y,sizeof(x))
  7 #define LL long long
  8 #define INF 1000000
  9 using namespace std;
 10 struct edge
 11 {
 12     int u,v,w,nxt;
 13     #define u(x) ed[x].u
 14     #define v(x) ed[x].v
 15     #define w(x) ed[x].w
 16     #define n(x) ed[x].nxt
 17 }ed[5000000];
 18 int first[300000],num_e;
 19 #define f(x) first[x]
 20 char map[510][510];
 21 int up[510][510],un[510][510];
 22 int le[510][510],re[510][510];
 23 int n,m;
 24 int cx,cy,fx,fy;
 25 inline int get(int i,int j){return (i-1)*m+j;}
 26 inline pair<int,int> ret(int val){return MP(val/m+1,val%m);}
 27 int dis[300010];
 28 bool v[300000];
 29 void dist(int st)
 30 {
 31     ma(dis,0x7f);
 32     priority_queue<pair<int,int> >q;
 33     dis[st]=0;q.push(MP(0,st));
 34     while(!q.empty())
 35     {
 36         int x=q.top().second;q.pop();
 37         if(v[x])continue;v[x]=1;
 38         for(int i=f(x);i;i=n(i))
 39         if(dis[x]+w(i)<dis[v(i)])
 40             dis[v(i)]=dis[x]+w(i),    
 41             q.push(MP(-dis[v(i)],v(i)));
 42     }
 43 }
 44 inline void add(int u,int v,int w);
 45 signed main()
 46 {
 47     cin>>n>>m;
 48     for(int i=1;i<=n;i++)
 49         scanf("%s",map[i]+1);
 50     for(int i=1;i<=n;i++)
 51         for(int j=1;j<=m;j++)
 52         {
 53             if(map[i][j]=='C')cx=i,cy=j;
 54             if(map[i][j]=='F')fx=i,fy=j;
 55             if(map[i][j]=='#')
 56             up[i][j]=un[i][j]=le[i][j]=re[i][j]=INF;
 57             else
 58             {
 59                 for(int k=i-1;k>0;k--)//
 60                 if(map[k][j]=='#'){up[i][j]=k+1;break;}
 61                 for(int k=i+1;k<=n;k++)//
 62                 if(map[k][j]=='#'){un[i][j]=k-1;break;}
 63                 for(int k=j-1;k>0;k--)//
 64                 if(map[i][k]=='#'){le[i][j]=k+1;break;}
 65                 for(int k=j+1;k<=m;k++)//
 66                 if(map[i][k]=='#'){re[i][j]=k-1;break;}
 67             }
 68         }
 69     for(int i=1;i<=n;i++)            
 70         for(int j=1;j<=m;j++)
 71         if(map[i][j]!='#')
 72         {
 73             if(map[i-1][j]!='#')add(get(i,j),get(i-1,j),1);//,add(get(i-1,j),get(i,j),1);//
 74             if(map[i+1][j]!='#')add(get(i,j),get(i+1,j),1);//,add(get(i+1,j),get(i,j),1);//
 75             if(map[i][j-1]!='#')add(get(i,j),get(i,j-1),1);//,add(get(i,j-1),get(i,j),1);//
 76             if(map[i][j+1]!='#')add(get(i,j),get(i,j+1),1);//,add(get(i,j+1),get(i,j),1);// 77             //
 78             {
 79                 add(get(i,j),get(un[i][j],j),i-up[i][j]+1);//
 80                 add(get(i,j),get(i,le[i][j]),i-up[i][j]+1);//
 81                 add(get(i,j),get(i,re[i][j]),i-up[i][j]+1);//
 82             }
 83             //
 84             {
 85                 add(get(i,j),get(up[i][j],j),un[i][j]-i+1);//
 86                 add(get(i,j),get(i,le[i][j]),un[i][j]-i+1);//
 87                 add(get(i,j),get(i,re[i][j]),un[i][j]-i+1);//
 88             }
 89             //
 90             {
 91                 add(get(i,j),get(up[i][j],j),j-le[i][j]+1);//
 92                 add(get(i,j),get(un[i][j],j),j-le[i][j]+1);//
 93                 add(get(i,j),get(i,re[i][j]),j-le[i][j]+1);//
 94             }
 95             //
 96             {
 97                 add(get(i,j),get(up[i][j],j),re[i][j]-j+1);//
 98                 add(get(i,j),get(un[i][j],j),re[i][j]-j+1);//
 99                 add(get(i,j),get(i,le[i][j]),re[i][j]-j+1);//
100             }
101         }
102     dist(get(cx,cy));
103     printf("%d
",dis[get(fx,fy)]);
104 }
105 inline void add(int u,int v,int w)
106 {
107     if(u==v)return;
108     ++num_e;
109     u(num_e)=u;
110     v(num_e)=v;
111     w(num_e)=w;
112     n(num_e)=f(u);
113     f(u)=num_e;
114 }
View Code
原文地址:https://www.cnblogs.com/Al-Ca/p/11318850.html