Codevs 2370 小机房的树
来源:互联网 发布:使用pptv网络电视播放 编辑:程序博客网 时间:2024/05/18 22:43
http://codevs.cn/problem/2370/
倍增LCA版本
代码
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using namespace std;int n,m,u,v,c,tot;int next[50001*2],first[50001],deep[50001],rank[50001],anc[50001][25];struct edge{ int t; int d;}l[100001];void build(int u,int v,int c){ l[++tot].t=v; l[tot].d=c; next[tot]=first[u]; first[u]=tot;}void dfs(int u,int fa,int w){ deep[u]=deep[fa]+1; anc[u][0]=fa; rank[u]=w; for(int i=1;anc[u][i-1];i++) { anc[u][i]=anc[anc[u][i-1]][i-1]; } for(int i=first[u];i!=-1;i=next[i])//for(int i=first[u];i;i=next[i])i不为0 { int v=l[i].t; if(!deep[v]) { dfs(v,u,w+l[i].d); } }}int ask_lca(int x,int y){ if(deep[x]<deep[y]) swap(x,y); if(deep[x]>deep[y]) { int dd=deep[x]-deep[y]; for(int i=0;i<=20;i++) { if(dd&(1<<i)) { x=anc[x][i]; } } } if(x!=y) { for(int i=20;i>=0;i--) { if(anc[x][i]!=anc[y][i]) { x=anc[x][i]; y=anc[y][i]; } } } if(x==y) return x; else return anc[x][0];}int main(){ memset(first,-1,sizeof(first)); scanf("%d",&n); for(int i=1;i<=n-1;i++) { scanf("%d%d%d",&u,&v,&c); build(u,v,c); build(v,u,c); } dfs(0,0,0); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); printf("%d\n",rank[u]+rank[v]-(2*rank[ask_lca(u,v)])); } return 0;}
树链剖分版本
代码
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;typedef long long ll;int n,m,ru,rv,rw,a,b,tot;int first[1000010],nxt[1000010],deep[1000010],f[1000010],top[1000010],siz[1000010],son[1000010],rank[1000010];struct edge{ int u,v,w;}l[1000010];void add(int f,int t,int c){ l[++tot]=(edge){f,t,c}; nxt[tot]=first[f]; first[f]=tot;}void dfs_1(int k,int fa,int d){ deep[k]=d; f[k]=fa; siz[k]=1; for(int i=first[k];i!=-1;i=nxt[i]) { int x=l[i].v; if(x==fa) continue; dfs_1(x,k,d+1); siz[k]+=siz[x]; if(!son[k]||siz[x]>siz[son[k]]) son[k]=x; }}void dfs_2(int k,int num){ top[k]=num; if(!son[k]) return; dfs_2(son[k],num); for(int i=first[k];i!=-1;i=nxt[i]) { int x=l[i].v; if(x!=son[k]&&x!=f[k]) dfs_2(x,x); }}void dfs(int k,int d){ rank[k]=d; for(int i=first[k];i!=-1;i=nxt[i]) { int x=l[i].v; if(x!=f[k]) dfs(x,d+l[i].w); }}ll find_lca(int x,int y){ int f1=top[x],f2=top[y]; ll ans=0; while(f1!=f2) { if(deep[f1]<deep[f2]) { f1=f1^f2; f2=f1^f2; f1=f1^f2; x=x^y; y=x^y; x=x^y; } ans+=rank[x]-rank[f[f1]];//注意边界问题 x=f[f1]; f1=top[x]; } if(deep[x]>deep[y]) ans+=rank[x]-rank[y]; if(deep[y]>=deep[x]) ans+=rank[y]-rank[x]; return ans;}int main(){ memset(first,-1,sizeof(first)); scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d%d",&ru,&rv,&rw); add(ru,rv,rw); add(rv,ru,rw); } tot=0; dfs_1(0,0,1); dfs_2(0,0); dfs(0,0); scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); printf("%lld\n",find_lca(a,b)); } return 0;}
阅读全文
0 0
- 【codevs 2370】小机房的树
- [LCA][CODEVS 2370]小机房的树
- Codevs 2370 小机房的树
- Codevs 2370 小机房的树
- 【codevs 2370】小机房的树
- Codevs 2370 小机房的树
- codevs 2370 小机房的树
- 【codevs 2370】小机房的树
- Codevs 2370 小机房的树
- 【codevs 2370】小机房的树
- codevs 2370小机房的树
- Codevs 2370 小机房的树
- codevs 2370 小机房的树 (lca)
- Codevs 2370 小机房的树
- codevs —— 2370 小机房的树 倍增LCA
- Codevs 2370 小机房的树 LCA 树上倍增
- codevs 2370 小机房的树(lca)
- codevs 2370 小机房的树 (LCA)
- 别人家的kalman 一
- 2017.11.09 matlab笔记
- Android应用方法数超过64K学习笔记
- Selenium WebDriver 中鼠标事件
- 第十一周项目2
- Codevs 2370 小机房的树
- UIScrollView跨屏截图
- HTML 块级元素行内元素
- Rxjava
- tomcat启动错误:严重: Error initializing endpoint java.lang.Exception: Socket bind failed: [730048] ???????
- Mysql语句处理排序的两种方式
- java 大小写转换
- Machine Learning in Action
- 尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题