1. 程式人生 > >German Collegiate Programming Contest 2018? A. Attack on Alpha-Zet

German Collegiate Programming Contest 2018? A. Attack on Alpha-Zet

順序 技術分享 a-z contest 路徑 print bfs class roo

題目鏈接https://nanti.jisuanke.com/t/28852

技術分享圖片

技術分享圖片

題目大意是 h*w 的平面,每兩個點有且僅有一條路徑,類似於封閉的聯通空間,然後在這h*w個點中選取(標記為1~N)N個點(給了坐標),求從1號點按1~N的順序走到N號點的路程。

練習賽的時候沒有思路,隊友說可以建樹,但還是不清不楚沒寫出來。

做法是LCA。

將封閉的聯通空間建樹(點的位置與字符的位置有點麻煩),然後按順序求兩點的最近的公共祖先求深度得距離,最後得路程,算是一道LCA的模板。

技術分享圖片
  1 #include <bits/stdc++.h>
  2 #define fir first
  3 #define
sec second 4 #define EPS 1e-12 5 using namespace std; 6 7 typedef long long LL; 8 typedef pair<int , int > pii; 9 const int MAXN=1000000+6; 10 const int DEG=20; 11 12 struct Edge{ 13 int to,nxt; 14 }edge[MAXN*2]; 15 int head[MAXN],tot; 16 17 void addEdge(int u,int v){ 18 edge[tot].to=v;
19 edge[tot].nxt=head[u]; 20 head[u]=tot++; 21 } 22 void init(){ 23 tot=0; 24 memset(head,-1,sizeof(head)); 25 } 26 int fa[MAXN][DEG]; 27 int deg[MAXN]; 28 29 void BFS(int root){ 30 queue< int > que; 31 deg[root]=0; 32 fa[root][0]=root; 33 que.push(root);
34 while(!que.empty()){ 35 int tmp=que.front();que.pop(); 36 for(int i=1;i<DEG;++i) 37 fa[tmp][i]=fa[fa[tmp][i-1]][i-1]; 38 for(int i=head[tmp];i!=-1;i=edge[i].nxt){ 39 int v=edge[i].to; 40 if(v==fa[tmp][0]) continue; 41 deg[v]=deg[tmp]+1; 42 fa[v][0]=tmp; 43 que.push(v); 44 } 45 } 46 } 47 48 int LCA(int u,int v){ 49 if(deg[u]>deg[v]) swap(u,v); 50 int hu=deg[u],hv=deg[v]; 51 int tu=u,tv=v; 52 for(int det=hv-hu,i=0;det;det>>=1,++i) 53 if(det&1) tv=fa[tv][i]; 54 if(tu==tv) return tu; 55 for(int i=DEG-1;i>=0;--i){ 56 if(fa[tu][i]==fa[tv][i]) 57 continue; 58 tu=fa[tu][i]; 59 tv=fa[tv][i]; 60 } 61 return fa[tu][0]; 62 } 63 64 char maze[1010][2020]; 65 int H,W; 66 67 void Judge(int cur,int xx,int yy){ 68 int i=xx,j=(yy+1)/2; 69 if(maze[xx-1][yy]!=_){ 70 int to=(i-2)*W+j; 71 addEdge(cur,to); 72 } 73 if(maze[xx][yy]!=_){ 74 int to=(i)*W+j; 75 addEdge(cur,to); 76 } 77 if(maze[xx][yy-1]!=|){ 78 int to=(i-1)*W+j-1; 79 addEdge(cur,to); 80 } 81 if(maze[xx][yy+1]!=|){ 82 int to=(i-1)*W+j+1; 83 addEdge(cur,to); 84 } 85 } 86 87 LL caldist(int u,int v){ 88 int ace=LCA(u,v); 89 return deg[u]+deg[v]-2*deg[ace]; 90 } 91 92 int main() 93 { 94 init(); 95 scanf("%d%d%*c",&H,&W); 96 for(int i=0;i<=H;++i){ 97 scanf("%[^\n]%*c",maze[i]); 98 } 99 for(int i=1;i<=H;++i){ 100 for(int j=1;j<=W;++j){ 101 int tmp=(i-1)*W+j; 102 int xx=i,yy=2*j-1; 103 Judge(tmp,xx,yy); 104 } 105 } 106 BFS(1); 107 LL ans=0; 108 int N,xi,yi; 109 scanf("%d%d%d",&N,&xi,&yi); 110 int old=(xi-1)*W+yi,aft; 111 for(int i=1;i<N;++i){ 112 scanf("%d%d",&xi,&yi); 113 aft=(xi-1)*W+yi; 114 ans+=caldist(old,aft); 115 old=aft; 116 } 117 printf("%lld\n",ans); 118 return 0; 119 }
View Code

German Collegiate Programming Contest 2018? A. Attack on Alpha-Zet