【codevs 1036】商务旅行
2017-09-02 09:57
239 查看
lca
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<cmath> #include<cstring> using namespace std; const int maxn=30000+5; int fa[maxn][25],deep[maxn],dist[maxn]; int n,m,tot,first[maxn],next[maxn<<1]; struct edge { int f,t,v; }es[maxn<<1]; void build(int f,int t,int v) { es[++tot]=(edge){f,t,v}; next[tot]=first[f]; first[f]=tot; } void init(int q,int h) { for(int i=first[h];i;i=next[i]) { int at=es[i].t,av=es[i].v; if(at==q) continue; fa[at][0]=h; dist[at]=dist[h]+av; deep[at]=deep[h]+1; init(h,at); } } void make_lca() { for(int i=1;i<=log2(n);i++) for(int j=1;j<=n;j++) fa[j][i]=fa[fa[j][i-1]][i-1]; } int lca(int x,int y) { if(deep[x]<deep[y]) swap(x,y); for(int i=log2(m);i>=0;i--) { if(deep[fa[x][i]]>=deep[y]) x=fa[x][i]; } if(x==y) return x; for(int i=log2(n);i>=0;i--) { if(fa[x][i]!=fa[y][i]) { x=fa[x][i]; y=fa[y][i]; } } return fa[x][0]; } int main() { scanf("%d",&n); for(int i=1;i<n;i++) { int v,u; scanf("%d%d",&v,&u); build(v,u,1); build(u,v,1); } init(1,1); make_lca(); scanf("%d",&m); int ans=0; for(int i=1;i<=m;i++) { int a,la; scanf("%d",&a); if(i==1) la=a; else { ans+=dist[a]+dist[la]-2*(dist[lca(a,la)]); la=a; } } printf("%d\n",ans); return 0; }
相关文章推荐
- 【codevs 1036】商务旅行
- codevs 1036 商务旅行
- 【codevs 1036】商务旅行
- codevs 1036 商务旅行 LCA 解题报告
- Codevs 1036:商务旅行——题解
- 【wikioi】1036商务旅行
- 1036 商务旅行(LCA例题)
- Codevs 1036 商务旅行
- 【最近公共祖先】【块状树】CODEVS 1036 商务旅行
- Codves 1036 商务旅行
- Codevs_P1036 商务旅行(LCA)
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
- Codevs P1036 商务旅行
- 1036 商务旅行
- wikioi1036 商务旅行 挺水的lca
- codevs 1036 商务旅行 (倍增LCA)
- Codevs1036 商务旅行 LCA【pascal】
- 1036 商务旅行
- 倍增LCA code[vs]1036商务旅行
- 【wikioi】1036商务旅行