POJ 1986 裸的LCA
2016-10-26 11:15
423 查看
思路:搞了一发链剖
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 88888 int n,m,first ,next ,v ,w ,tot,xx,yy,zz,k; int top ,size ,deep ,son ,fa ,weight ; void add(int x,int y,int z){ w[tot]=z,v[tot]=y; next[tot]=first[x],first[x]=tot++; } void dfs(int x){ size[x]=1; for(int i=first[x];~i;i=next[i]) if(v[i]!=fa[x]){ fa[v[i]]=x; deep[v[i]]=deep[x]+1; weight[v[i]]=weight[x]+w[i]; dfs(v[i]); size[x]+=size[v[i]]; if(size[son[x]]<size[v[i]])son[x]=v[i]; } } void dfs2(int x,int tp){ top[x]=tp; if(son[x])dfs2(son[x],tp); for(int i=first[x];~i;i=next[i]){ if(v[i]!=fa[x]&&v[i]!=son[x]){ dfs2(v[i],v[i]); } } } int lca(int x,int y){ int fx=top[x],fy=top[y]; while(fx!=fy){ if(deep[fx]<deep[fy]) swap(fx,fy),swap(x,y); x=fa[fx],fx=top[x]; } if(deep[x]<deep[y])return x; return y; } int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&xx,&yy,&zz),getchar(),getchar(),getchar(); add(xx,yy,zz),add(yy,xx,zz); } dfs(1),dfs2(1,1); scanf("%d",&k); for(int i=1;i<=k;i++){ scanf("%d%d",&xx,&yy); printf("%d\n",weight[xx]+weight[yy]-2*weight[lca(xx,yy)]); } }
相关文章推荐
- POJ 1986 Distance Queries (在线LCA转RMQ)
- POJ 1986 裸的LCA
- B - 雲に潜む一つ眼の化生 POJ - 1986 LCA->RMQ模板【下标从1开始】
- POJ 1986 Distance Queries【LCA】
- Poj 1986 Distance Queries【LCA】
- POJ 1986 Distance Queries(LCA)
- poj 1986LCA离线dfs+并查集
- POJ - 1986 Distance Queries(LCA离线)
- Distance Queries - POJ 1986 LCA
- poj 1986 最近公共祖先 (lca 倍增)
- POJ 1986 Distance Queries(在线LCA)
- |poj 1986|LCA|Distance Queries
- poj 1986 Distance Queries(LCA离线Tarjan算法)
- poj 1986LCA离线dfs+并查集
- POJ 1986 LCA,tarjan实现
- POJ 1986 Distance Queries LCA和RMQ
- POJ 1986 Distance Queries(LCA Tarjan离线算法)
- Distance Queries POJ - 1986 (LCA在线方法求解 公共祖先(带权值))
- POJ 1986 Distance Queries(查询两点距离,LCA)
- 用于求最近公共祖先(LCA)的 Tarjan算法–以POJ1986为例(转)