Codves 1036 商务旅行
2016-11-03 00:00
197 查看
题面在这 ↓ 自己拿。
http://codevs.cn/problem/1036/
今天下午打倍增练练手,感谢红太阳的help。倍增的思想是一次跳2的n次方步来减小时间复杂度 。倍增一次 O(longn)。借助位运算和二进制来维护处理。
手读完全版 (QwQ)可以处理负数。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int maxx=70000; int n,m; int tot=0,first[maxx],next[maxx]; struct lc { int f,t,d; }es[maxx]; void build(int f,int t) { es[++tot]=(lc){f,t}; next[tot]=first[f]; first[f]=tot; } int sd[maxx],fa[maxx][30]; void dfs(int x) { for(int i=first[x];i!=0;i=next[i]) { int v=es[i].t; if(sd[v]==0) { sd[v]=sd[x]+1; fa[v][0]=x; for(int t=1;t<=20;t++) fa[v][t]=fa[fa[v][t-1]][t-1]; dfs(v); } } } int lca(int u,int v) { if(sd[u]>sd[v]) swap(u,v); int tt=sd[v]-sd[u]; for(int i=0;i<=20;i++) if((tt>>i)&1==1) v=fa[v][i]; if(u==v) return u; for(int i=20;i>=0;i--) { if(fa[v][i]!=fa[u][i]) { v=fa[v][i]; u=fa[u][i]; } } return fa[u][0]; } void read(int &a) { a=0; char c=getchar(); int fs=1; while (c<'0'||c>'9') { if(c=='-') fs=-1; c=getchar(); } while (c>='0'&&c<='9') { a*=10; a+=c-'0'; c=getchar(); } a*=fs; } int zz[maxx]; int main() { read(n); int x,y; for(int i=1;i<n;i++) { read(x);read(y); build(x,y); build(y,x); } sd[1]=1; dfs(1); read(m); for(int i=1;i<=m;i++) read(zz[i]); int t=0,ans=0; for(int i=1;i<m;i++) { t=2*sd[lca(zz[i],zz[i+1])]-sd[zz[i]]-sd[zz[i+1]]; ans+=t; } printf("%d",-ans); return 0; }
相关文章推荐
- Codves 1036 商务旅行
- wikioi1036 商务旅行 挺水的lca
- 【codevs1036】商务旅行,LCA练习
- Codevs1036 商务旅行 LCA【pascal】
- CODE[VS] 1036商务旅行
- codevs 1036 商务旅行 (lca)
- codevs1036 商务旅行 lcs倍增
- [CodeVS1036] 商务旅行
- 【wikioi】1036商务旅行
- 【基础练习】【倍增LCA】codevs1036 商务旅行题解
- codevs 1036 商务旅行
- CodeVs.1036 商务旅行 ( LCA 最近公共祖先 )
- codevs 1036 商务旅行 LCA 解题报告
- 商务旅行_codevs1036_lca
- 1036 商务旅行
- 1036商务旅行
- 1036 商务旅行
- codevs 1036 商务旅行(Targin求LCA)
- 倍增LCA code[vs]1036商务旅行
- codevs 1036 商务旅行 题解报告