题意:Misha 和 Grisha 是2个很喜欢恶作剧的孩子, 每天早上 Misha 会从地铁站 s 通过最短的路到达地铁站 f, 并且在每个地铁站上都写上一句话, 然后Grisha 再从地铁站 t 通过最短的路到达地铁站 f, 并且记录下路途上被Misha写上字的地铁站数目,并且当天晚上会人会将地铁站清理干净,不会干扰第二天的计数, 现在给你3个地铁站 a, b, c, 现在求Misha记录的数目最大能是多少。
代码:求出Lca(a,b) Lca(a,c) Lca(b,c) 再找到深度最大的那个点, 我门可以通过画图发现 这个点是一个3叉路口, 从这个路口往每一地铁站走的路都是有效长度,最后找到有效长度就是答案了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define ULL unsigned LL 5 #define fi first 6 #define se second 7 #define lson l,m,rt<<1 8 #define rson m+1,r,rt<<1|1 9 #define max3(a,b,c) max(a,max(b,c)) 10 const int INF = 0x3f3f3f3f; 11 const LL mod = 1e9+7; 12 typedef pair<int,int> pll; 13 const int N = 1e5+5; 14 struct Node{ 15 int to; 16 int nt; 17 }e[N<<1]; 18 int head[N], anc[20][N], deep[N]; 19 int tot = 0; 20 void add(int u, int v){ 21 e[tot].to = v; 22 e[tot].nt = head[u]; 23 head[u] = tot++; 24 } 25 void dfs(int u, int o){ 26 deep[u] = deep[o] + 1; 27 for(int i = head[u]; ~i; i = e[i].nt){ 28 if(o != e[i].to){ 29 anc[0][e[i].to] = u; 30 for(int j = 1; j < 20; j++) anc[j][e[i].to] = anc[j-1][anc[j-1][e[i].to]]; 31 dfs(e[i].to,u); 32 } 33 } 34 } 35 int lca(int u, int v){ 36 if(deep[u] < deep[v]) swap(u, v); 37 for(int i = 19; i >= 0; i--) if(deep[v] <= deep[anc[i][u]]) u = anc[i][u]; 38 if(u == v) return v; 39 for(int i = 19; i >= 0; i--) if(anc[i][u] != anc[i][v]) u = anc[i][u], v = anc[i][v]; 40 return anc[0][u]; 41 } 42 int dis(int u, int v) 43 { 44 return deep[u]+deep[v]-2*deep[lca(u,v)]; 45 } 46 int main(){ 47 int n, m, v; 48 scanf("%d%d", &n, &m); 49 memset(head, -1, sizeof(head)); 50 for(int i = 2; i <= n; i++){ 51 scanf("%d", &v); 52 add(i,v); 53 add(v,i); 54 } 55 dfs(1,0); 56 int a, b, c; 57 for(int i = 1; i <= m; i++){ 58 scanf("%d%d%d",&a,&b,&c); 59 int t1 = lca(a, b), t2 = lca(b,c), t3 = lca(a,c); 60 //cout << t1 <<' ' << t2 << ' ' << t3 << endl; 61 if(deep[t1] < deep[t2]) t1 = t2; 62 if(deep[t1] < deep[t3]) t1 = t3; 63 int ans = max3(dis(t1,a), dis(t1,b), dis(t1,c)); 64 printf("%d ",ans+1); 65 } 66 return 0; 67 }