poj 1986 Distance Queries(LCA:倍增/离线)
2013-08-15 09:31
197 查看
计算树上的路径长度。input要去查poj 1984。
任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离。输出d[u]+d[v]-2*d[lca(u,v)]。
倍增求解:
View Code
任意建一棵树,利用树形结构,将问题转化为u,v,lca(u,v)三个点到根的距离。输出d[u]+d[v]-2*d[lca(u,v)]。
倍增求解:
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> #define rep(i,a,b) for(int i=a;i<=b;i++) #define clr(a,m) memset(a,m,sizeof(a)) using namespace std; const int MAXN=44444; struct Edge{ int v,next,c; Edge(){} Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){} }edge[MAXN<<1]; struct EDGE{ int u,v; int ans; EDGE(){} EDGE(int _u,int _v):u(_u),v(_v),ans(-1){} }; int head[MAXN],tol; int p[MAXN],vis[MAXN],dis[MAXN]; queue<int>q; vector<int>query[MAXN]; vector<EDGE>G; void init() { tol=0; clr(head,-1); } void add(int u,int v,int c) { edge[tol]=Edge(v,c,head[u]); head[u]=tol++; } void build(int m) { init(); rep(i,1,m){ int u,v,c; scanf("%d%d%d%*s",&u,&v,&c); add(u,v,c); add(v,u,c); } int k; scanf("%d",&k); rep(i,1,k){ int u,v,siz; scanf("%d%d",&u,&v); G.push_back(EDGE(u,v)); siz=G.size(); query[u].push_back(siz-1); G.push_back(EDGE(v,u)); siz=G.size(); query[v].push_back(siz-1); } } void bfs(int x) { clr(vis,0); clr(dis,0); while(!q.empty()) q.pop(); q.push(x); vis[x]=1; dis[x]=0; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(vis[v]) continue; q.push(v); vis[v]=1; dis[v]=dis[u]+edge[i].c; } } } int find(int x) { return (x==p[x])?x:(p[x]=find(p[x])); } void dfs(int x) { vis[x]=1; for(int i=head[x];i!=-1;i=edge[i].next) { int v=edge[i].v; if(vis[v]) continue; dfs(v); p[v]=x; } int siz =query[x].size()-1; rep(i,0,siz) { int t=query[x][i]; if(vis[G[t].v]){ G[t].ans=find(G[t].v); } } } void LCA(int rt,int n) { clr(vis,0); rep(i,1,n) p[i]=i; dfs(rt); } void PRT() { int siz=G.size(); for(int i=0;i<siz;i+=2) { int u=G[i].u; int v=G[i].v; if(G[i].ans!=-1) printf("%d\n",dis[u]+dis[v]-2*dis[G[i].ans]); else printf("%d\n",dis[u]+dis[v]-2*dis[G[i^1].ans]); } } int main() { int n,m; scanf("%d%d",&n,&m); build(m); bfs(1); LCA(1,n); PRT(); return 0; }
View Code
相关文章推荐
- poj 1330 LCA (倍增+离线Tarjan)
- poj 1986LCA离线dfs+并查集
- POJ - 3728 The merchant【离线LCA[倍增法]】
- poj 1986 Distance Queries(LCA离线Tarjan算法)
- POJ 1986 Distance Queries(离线tarjan-LCA)
- poj 1986 Distance Queries 离线LCA
- POJ 1986 Distance Queries(LCA在线和离线)
- POJ - 1986 Distance Queries(LCA离线)
- poj 1986 最近公共祖先 (lca 倍增)
- POJ 题目1986 Distance Queries(LCA 离线)
- 【POJ】 1986 Distance Queries 离线LCA
- poj 1986 Distance Queries (LCA 倍增)
- POJ 1986 Distance Queries(离线LCA)
- POJ 1986 Distance Queries (离线LCA)
- poj 1986LCA离线dfs+并查集
- POJ 1330 LCA倍增模板题
- (LCA倍增) poj 1330
- POJ 1330 LCA最近公共祖先 离线tarjan算法
- poj 1986 Distance Queries 带权lca 模版题
- POJ 1986 裸的LCA