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

Posted kiritsugu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了German Collegiate Programming Contest 2018? A. Attack on Alpha-Zet相关的知识,希望对你有一定的参考价值。

题目链接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("%[^
]%*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
",ans);
118     return 0;
119 }
View Code

 

以上是关于German Collegiate Programming Contest 2018? A. Attack on Alpha-Zet的主要内容,如果未能解决你的问题,请参考以下文章

(寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)

(寒假开黑gym)2017-2018 ACM-ICPC German Collegiate Programming Contest (GCPC 2017)

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

2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program(点双连通)

ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2018) Syr

ACM International Collegiate Programming Contest, JUST Collegiate Programming Contest (2018)