Rogu p31_lca, HDU2586, rogu P1967 freight car transportation, multiplication lca, tree multiplication, p3w.lcap1967
Multiply lca board loogu P3379
1 #include<cstdio> 2 struct E 3 { 4 int to,next; 5 }e[1001000]; 6 int f1[500100],anc[500100][20],log2n,deep[500100],n,m,s,ne; 7 bool vis[500100]; 8 void dfs(int x,int fa) 9 {10 int i,k;11 vis[x]=1;12 anc[x][0]=fa;13 deep[x]=deep[fa]+1;14 for(i=1;i<=log2n;i++)15 anc[x][i]=anc[anc[x][i-1]][i-1];16 for(k=f1[x];k!=0;k=e[k].next)17 if(!vis[e[k].to])18 dfs(e[k].to,x);19 }20 int lca(int x,int y)21 {22 int t,i;23 if(deep[x]<deep[y]){t=x;x=y;y=t;}24 for(t=deep[x]-deep[y],i=0;t>0;t>>=1,i++)25 if(t&1) x=anc[x][i];26 if(x==y) return x;27 for(i=log2n;i>=0;i--)28 if(anc[x][i]!=anc[y][i])29 {30 x=anc[x][i];31 y=anc[y][i];32 }33 return anc[x][0];34 }35 int main()36 {37 int i,x,y,a,b;38 scanf("%d%d%d",&n,&m,&s);39 while((1<<(log2n+1))<=n) log2n++;40 for(i=1;i<n;i++)41 {42 scanf("%d%d",&x,&y);43 e[++ne].to=y;44 e[ne].next=f1[x];45 f1[x]=ne;46 e[++ne].to=x;47 e[ne].next=f1[y];48 f1[y]=ne;49 }50 dfs(s,0);51 while(m--)52 {53 scanf("%d%d",&a,&b);54 printf("%d\n",lca(a,b));55 }56 return 0;57 }
How far away? HDU-2586 (two points on the tree)
The method is to find the distance from dis [I] to the root node, then two points, the distance between B is $ dis [a] + dis [B]-2 * dis [lca (a, B)] $
Error notes:
Line 2 is written as anc [x] [I] = anc [fa] [I-1];
2. 18 rows missing
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 typedef long long LL; 7 struct Edge 8 { 9 LL to,d,nxt;10 }e[80100];11 LL T,n,m,ne;12 LL f1[40100],deep[40100],anc[40100][17],log2n;13 LL dis[40100];14 void dfs(LL x,LL fa)15 {16 LL i,k;17 anc[x][0]=fa;18 deep[x]=deep[fa]+1;19 for(i=1;i<=log2n;i++)20 anc[x][i]=anc[anc[x][i-1]][i-1];21 for(k=f1[x];k!=0;k=e[k].nxt)22 if(e[k].to!=fa)23 {24 dis[e[k].to]=dis[x]+e[k].d;25 dfs(e[k].to,x);26 }27 }28 LL lca(LL x,LL y)29 {30 LL t,i;31 if(deep[x]<deep[y]) swap(x,y);32 for(t=deep[x]-deep[y],i=0;t>0;t>>=1,i++)33 if(t&1) x=anc[x][i];34 if(x==y) return x;35 for(i=log2n;i>=0;i--)36 if(anc[x][i]!=anc[y][i])37 {38 x=anc[x][i];39 y=anc[y][i];40 }41 return anc[x][0];42 }43 int main()44 {45 LL i,a,b,w,t;46 scanf("%lld",&T);47 while(T--)48 {49 ne=0;50 memset(f1,0,sizeof(f1));51 scanf("%lld%lld",&n,&m);52 log2n=log2(n);53 for(i=1;i<n;i++)54 {55 scanf("%lld%lld%lld",&a,&b,&w);56 e[++ne].to=b;57 e[ne].nxt=f1[a];58 e[ne].d=w;59 f1[a]=ne;60 e[++ne].to=a;61 e[ne].nxt=f1[b];62 e[ne].d=w;63 f1[b]=ne;64 }65 dfs(1,0);66 for(i=1;i<=m;i++)67 {68 scanf("%lld%lld",&a,&b);69 t=lca(a,b);70 printf("%lld\n",dis[a]-dis[t]+dis[b]-dis[t]);71 }72 }73 return 0;74 }
Luogu P1967 freight car transportation (find the shortest side of the path with the longest shortest side in all the paths between two points in the figure)
First, you can directly retrieve the maximum Spanning Tree of the source image and query the answer only.
The reason is that when kruskal generates the maximum Spanning Tree, the edge is taken from large to small Based on the Edge Weight. When determining whether an edge is not obtained, the edge is not obtained only when two points are connected. Otherwise, the edge will be obtained. If a and B are connected when determining whether to take an edge (a, B, w, so that the weight of any edge in the path connected by a and B must be greater than or equal to w (because they are all obtained before the current edge ), that is, the minimum edge weight of the path connected by a and B is greater than or equal to w. If the path between two points needs to pass the path from a to B, select (a, B, w) the path is certainly not better than the original path that makes a and B connected.
Then, this question is similar to the previous one. However, since the maximum and minimum values do not satisfy the range addition, we cannot simply use the prefix and the same as that. The correct method is similar to the process of doubling the lca to obtain 2 ^ I-level ancestor.
Set minn [I] [j] to represent the minimum edge weight from vertex I to the path of its 2 ^ j-level ancestor. Then $ minn [I] [j] = min (minn [I] [J-1], minn [anc [I] [J-1] [J-1]) $. Of course, minn [I] [0] is the edge right of his father's side. This array can be pre-processed in the dfs of the multiplication lca.
When querying, You can multiply the lca query, but for the operations on the node to jump up, before performing this operation, update the minimum edge weight of the path to be skipped to the known minimum edge weight.
Error records (local ):
Lines 1.47 and 48 are reversed.
Line 3 is written as anc [e [k]. to] = fa
3. 87 rows missing
4. 66 rows missing
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 struct E1 7 { 8 int a,b,w; 9 friend bool operator<(const E1& a,const E1& b) 10 { 11 return a.w>b.w; 12 } 13 }e1[50100]; 14 struct Edge 15 { 16 int to,d,nxt; 17 }e[20100]; 18 int fa[10100],q,n,m,ne,f1[10100],anc[10100][15],log2n,minn[10100][15],deep[10100]; 19 int find(int x) 20 { 21 return fa[x]==x?x:fa[x]=find(fa[x]); 22 } 23 void dfs(int x,int fa) 24 { 25 int i,k; 26 for(i=1;i<=log2n;i++) 27 { 28 anc[x][i]=anc[anc[x][i-1]][i-1]; 29 minn[x][i]=min(minn[x][i-1],minn[anc[x][i-1]][i-1]); 30 } 31 for(k=f1[x];k!=0;k=e[k].nxt) 32 if(e[k].to!=fa) 33 { 34 deep[e[k].to]=deep[x]+1; 35 anc[e[k].to][0]=x; 36 minn[e[k].to][0]=e[k].d; 37 dfs(e[k].to,x); 38 } 39 } 40 int get(int x,int y) 41 { 42 int t,ans=0x3f3f3f3f,i; 43 if(deep[x]<deep[y]) swap(x,y); 44 for(t=deep[x]-deep[y],i=0;t>0;t>>=1,i++) 45 if(t&1) 46 { 47 ans=min(ans,minn[x][i]); 48 x=anc[x][i]; 49 } 50 if(x==y) return ans; 51 for(i=log2n;i>=0;i--) 52 if(anc[x][i]!=anc[y][i]) 53 { 54 ans=min(ans,minn[x][i]); 55 ans=min(ans,minn[y][i]); 56 x=anc[x][i]; 57 y=anc[y][i]; 58 } 59 return min(ans,min(minn[x][0],minn[y][0])); 60 } 61 int main() 62 { 63 int i,t1,t2,a,b; 64 scanf("%d%d",&n,&m); 65 log2n=log2(n); 66 memset(minn,0x3f,sizeof(minn)); 67 for(i=1;i<=m;i++) 68 scanf("%d%d%d",&e1[i].a,&e1[i].b,&e1[i].w); 69 sort(e1+1,e1+m+1); 70 for(i=1;i<=n;i++) 71 fa[i]=i; 72 for(i=1;i<=m;i++) 73 { 74 t1=find(e1[i].a); 75 t2=find(e1[i].b); 76 if(t1==t2) continue; 77 e[++ne].to=e1[i].b; 78 e[ne].nxt=f1[e1[i].a]; 79 e[ne].d=e1[i].w; 80 f1[e1[i].a]=ne; 81 e[++ne].to=e1[i].a; 82 e[ne].nxt=f1[e1[i].b]; 83 e[ne].d=e1[i].w; 84 f1[e1[i].b]=ne; 85 fa[t1]=t2; 86 } 87 dfs(1,0); 88 scanf("%d",&q); 89 while(q--) 90 { 91 scanf("%d%d",&a,&b); 92 if(a>n||b>n||find(a)!=find(b)) 93 { 94 printf("-1\n"); 95 continue; 96 } 97 printf("%d\n",get(a,b)); 98 } 99 return 0;100 }