zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    几数之和的题目
    File类
    递归
    Collections
    Map集合
    泛型
    类型通配符
    可变参数
    异常
    Collection集合
  • 原文地址:https://www.cnblogs.com/Kiritsugu/p/9347535.html
Copyright © 2011-2022 走看看