题目描述 Description
小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力
输入描述 Input Description
第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点
输出描述 Output Description
一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。
样例输入 Sample Input
3
1 0 1
2 0 1
3
1 0
2 0
1 2
样例输出 Sample Output
1
1
2
lca裸题
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define N 71000 using namespace std; bool vis[N]; int n,m,x,y,z,tot,lca,ans,root; int deep[N],size[N],fa[N],top[N],sum[N],dad[N],head[N]; int read() { ,f=; char ch=getchar(); ; ch=getchar();} +ch-'; ch=getchar();} return x*f; } struct Edge { int to,dis,from,next; }edge[N<<]; int add(int x,int y,int z) { tot++; edge[tot].to=y; edge[tot].dis=z; edge[tot].next=head[x]; head[x]=tot; } int dfs(int x) { size[x]=; deep[x]=deep[fa[x]]+; // sum[x]=sum[fa[x]]+edge[x].dis; for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(fa[x]==to||vis[x]) continue; fa[to]=x; sum[to]=sum[x]+edge[i].dis; dfs(to); size[x]+=size[to]; } } int dfs1(int x) { ; if(!top[x]) top[x]=x; for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(fa[x]!=to&&size[to]>size[t]) t=to; } if(t&&!vis[t]) { top[t]=top[x]; dfs1(t); } for(int i=head[x];i;i=edge[i].next) { int to=edge[i].to; if(fa[x]!=to&&to!=t&&!vis[to]) dfs1(to); } } int LCA(int x,int y) { while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]]) swap(x,y); x=fa[top[x]]; } if(deep[x]>deep[y]) swap(x,y); return x; } int main() { n=read(); ;i<n;i++) { x=read(),y=read(),z=read(); add(x+,y+,z),add(y+,x+,z);//dad[x+1]=y+1; } /* for(int i=1;i<=n;i++) if(!dad[i]) {root=i; break;}*/ m=read();dfs(); memset(vis,,); while(m--) { x=read(),y=read(); x++,y++,lca=LCA(x,y); ans=sum[x]+sum[y]-*sum[lca]; printf("%d\n",ans); } }