题目链接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 }
原文地址:https://www.cnblogs.com/Kiritsugu/p/9347535.html
时间: 2024-11-20 17:01:15