本来觉得这是一道挺水的题目,后来觉得出题人挺变态的= =
半个小时敲完后,内存超限它给我看TLE,还是0ms,后来才发现内存限制64m
然后卡了一个小时后AC了。。
题目大意是在一棵树上找三点的最短路
依次挑两个点求LCA,再将LCA与第三个点再求LCA
求三次取最优就行了。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; ; struct node{ int to,next; }e[]; int sum,n,m,tot,logn,l,r,a,b,c,x,y,id; ],dep[maxn]; void insert(int u, int v, int c){ e[++tot].to=v; //e[tot].cost=c; e[tot].next=head[u]; head[u]=tot; } void dfs(int u, int f, int d){ dep[u]=d; fa[u][]=f; //dis[u][0]=c; ; i<=logn; i++) fa[u][i]=fa[fa[u][i-]][i-]; //for (int i=1; i<=logn; i++) dis[u][i]=dis[u][i-1]+dis[fa[u][i-1]][i-1]; ; i=e[i].next) if (e[i].to!=f) dfs(e[i].to,u,d+); } int lca(int u, int v){ if (dep[u]>dep[v]) swap(u,v); while (dep[u]<dep[v]){ ; i--) if (dep[u]<dep[fa[v][i]]){ //sum+=dis[v][i]; v=fa[v][i]; } //sum+=dis[v][0]; v=fa[v][]; } if (u==v) return u; ; i--) if (fa[u][i]!=fa[v][i]){ // sum+=dis[v][i]+dis[u][i]; u=fa[u][i]; v=fa[v][i]; } //sum+=dis[v][0]+dis[u][0]; u=fa[u][]; v=fa[v][]; return u; } int main(){ scanf("%d%d", &n, &m); tot=-; ; i<=n; i++) head[i]=-; //memset(head,-1,sizeof(head)); //memset(dis,0,sizeof(dis)); //memset(e,0,sizeof(e)); ; i<n; i++){ scanf("%d%d", &l, &r); insert(l,r,); insert(r,l,); } logn=; <<logn)<n) logn++; dfs(,,); ; i<=m; i++){ scanf("%d%d%d", &a, &b, &c); ; x=lca(a,b); y=lca(x,c); sum=dep[a]+dep[b]+dep[c]-dep[x]-dep[y]*; if (sum<ans){ ans=sum; id=x; } x=lca(a,c); y=lca(x,b); sum=dep[a]+dep[b]+dep[c]-dep[x]-dep[y]*; if (sum<ans){ ans=sum; id=x; } x=lca(b,c); y=lca(x,a); sum=dep[a]+dep[b]+dep[c]-dep[x]-dep[y]*; if (sum<ans){ ans=sum; id=x; } printf("%d %d\n", id, ans); } ; }