
这道题很卡常
但用一些优化 可过
问题
求一点到 三个不同点的距离最小
输出这个点 和这个距离
#define sum(a,b,c) (depth[a] + depth[b] + depth[c]) t,ab = lca(a,b),ac = lca(a,c),bc = lca(b,c); if(ab == ac) t = bc; if(ab == bc) t = ac; if(ac == bc) t = ab; printf("%d %d\n",t,sum(a,b,c) - sum(ab,ac,bc));
感性理解下
倍增的一些优化
for(reg i = 1;i <= n;i++) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); inline int lca(int a,int b) { if(depth[a] < depth[b]) swap(a,b); while(depth[a] > depth[b]) a = fa[a][lg[depth[a] - depth[b]] - 1]; if(a == b) return a; for(reg i = lg[depth[a]];i >= 0;i--) if(fa[a][i] != fa[b][i]) a = fa[a][i],b = fa[b][i]; return fa[a][0]; }
总结
少函数,非递归函数用宏
\(lca\),提前处理\(log\)
register int
变量名尽量小写,短
\(Code\)
#include <cstdio> #include <vector> #include <iostream> using namespace std; #define reg register int const int MAXN = 5e5 + 10; int cnt,fa[MAXN][30],lg[MAXN],head[MAXN],depth[MAXN],n,m; bool vis[MAXN]; struct node { int v,next; }edge[MAXN << 1]; template<typename T> inline T Read(T Type) { T x = 0; bool f = 0; char a = getchar(); while(!isdigit(a)) {if(a == '-') f = 1;a = getchar();} while(isdigit(a)) x = (x << 1) + (x << 3) + a - '0',a = getchar(); if(f) x *= -1; return x; } inline void addedge(int u,int v) { edge[++cnt].v = v; edge[cnt].next = head[u]; head[u] = cnt; } inline void prepare(int x) { vis[x] = 1; for(reg i = head[x];i;i = edge[i].next) { int v = edge[i].v; if(vis[v]) continue; fa[v][0] = x; depth[v] = depth[x] + 1; prepare(v); } } inline int lca(int a,int b) { if(depth[a] < depth[b]) swap(a,b); while(depth[a] > depth[b]) a = fa[a][lg[depth[a] - depth[b]] - 1]; if(a == b) return a; for(reg i = lg[depth[a]];i >= 0;i--) if(fa[a][i] != fa[b][i]) a = fa[a][i],b = fa[b][i]; return fa[a][0]; } #define sum(a,b,c) (depth[a] + depth[b] + depth[c]) int main() { n = Read(1),m = Read(1); for(reg i = 1;i < n;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v),addedge(v,u); } fa[1][0] = 1; for(reg i = 1;i <= n;i++) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); prepare(1); for(reg i = 1;i <= lg[n];i++) for(reg j = 1;j <= n;j++) fa[j][i] = fa[fa[j][i - 1]][i - 1]; int t,a,b,c,ab,ac,bc; for(reg i = 1;i <= m;i++) { a = Read(1),b = Read(1),c = Read(1),t,ab = lca(a,b),ac = lca(a,c),bc = lca(b,c); if(ab == ac) t = bc; if(ab == bc) t = ac; if(ac == bc) t = ab; printf("%d %d\n",t,sum(a,b,c) - sum(ab,ac,bc)); } return 0; }