poj 1986 Distance Queries(LCA:倍增/离线)
计算树上的路径长度。input要去查poj 1984。
任意建一棵树,利用树形结构,将问题转化为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=;
- const int POW = ;
- struct Edge{
- int v,next,c;
- Edge(){}
- Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
- }edge[MAXN<<];
- int head[MAXN],tol;
- int p[MAXN][POW],d[MAXN];
- int vis[MAXN],dis[MAXN];
- queue<int>q;
- void init()
- {
- tol=;
- clr(head,-);
- }
- void add(int u,int v,int c)
- {
- edge[tol]=Edge(v,c,head[u]);
- head[u]=tol++;
- }
- void bfs(int x)
- {
- clr(vis,);
- clr(dis,);
- while(!q.empty())
- q.pop();
- q.push(x);
- vis[x]=;
- dis[x]=;
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- for(int i=head[u];i!=-;i=edge[i].next)
- {
- int v=edge[i].v;
- if(vis[v])
- continue;
- q.push(v);
- vis[v]=;
- dis[v]=dis[u]+edge[i].c;
- }
- }
- }
- void dfs(int u,int fa){
- d[u]=d[fa]+;
- p[u][]=fa;
- for(int i=;i<POW;i++) p[u][i]=p[p[u][i-]][i-];
- for(int i=head[u];i!=-;i=edge[i].next){
- int v=edge[i].v;
- if(v==fa) continue;
- dfs(v,u);
- }
- }
- int lca( int a, int b ){
- if( d[a] > d[b] ) a ^= b, b ^= a, a ^= b;
- if( d[a] < d[b] ){
- int del = d[b] - d[a];
- for( int i = ; i < POW; i++ ) if(del&(<<i)) b=p[b][i];
- }
- if( a != b ){
- for( int i = POW-; i >= ; i-- )
- if( p[a][i] != p[b][i] )
- a = p[a][i] , b = p[b][i];
- a = p[a][], b = p[b][];
- }
- return a;
- }
- void LCA(int n)
- {
- clr(p,);
- d[]=;
- dfs(,);
- bfs();
- int k;
- scanf("%d",&k);
- int u,v;
- rep(i,,k){
- scanf("%d%d",&u,&v);
- printf("%d\n",dis[u]+dis[v]-*dis[lca(u,v)]);
- }
- }
- int main()
- {
- int n,m;
- scanf("%d%d",&n,&m);
- init();
- rep(i,,m){
- int u,v,c;
- scanf("%d%d%d%*s",&u,&v,&c);
- add(u,v,c);
- add(v,u,c);
- }
- LCA(n);
- return ;
- }
又用tarjin离线做了一遍= =
- #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=;
- struct Edge{
- int v,next,c;
- Edge(){}
- Edge(int _v,int _c,int _next):v(_v),c(_c),next(_next){}
- }edge[MAXN<<];
- struct EDGE{
- int u,v;
- int ans;
- EDGE(){}
- EDGE(int _u,int _v):u(_u),v(_v),ans(-){}
- };
- int head[MAXN],tol;
- int p[MAXN],vis[MAXN],dis[MAXN];
- queue<int>q;
- vector<int>query[MAXN];
- vector<EDGE>G;
- void init()
- {
- tol=;
- clr(head,-);
- }
- 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,,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,,k){
- int u,v,siz;
- scanf("%d%d",&u,&v);
- G.push_back(EDGE(u,v));
- siz=G.size();
- query[u].push_back(siz-);
- G.push_back(EDGE(v,u));
- siz=G.size();
- query[v].push_back(siz-);
- }
- }
- void bfs(int x)
- {
- clr(vis,);
- clr(dis,);
- while(!q.empty())
- q.pop();
- q.push(x);
- vis[x]=;
- dis[x]=;
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- for(int i=head[u];i!=-;i=edge[i].next)
- {
- int v=edge[i].v;
- if(vis[v])
- continue;
- q.push(v);
- vis[v]=;
- 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]=;
- for(int i=head[x];i!=-;i=edge[i].next)
- {
- int v=edge[i].v;
- if(vis[v])
- continue;
- dfs(v);
- p[v]=x;
- }
- int siz =query[x].size()-;
- rep(i,,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,);
- rep(i,,n)
- p[i]=i;
- dfs(rt);
- }
- void PRT()
- {
- int siz=G.size();
- for(int i=;i<siz;i+=)
- {
- int u=G[i].u;
- int v=G[i].v;
- if(G[i].ans!=-)
- printf("%d\n",dis[u]+dis[v]-*dis[G[i].ans]);
- else
- printf("%d\n",dis[u]+dis[v]-*dis[G[i^].ans]);
- }
- }
- int main()
- {
- int n,m;
- scanf("%d%d",&n,&m);
- build(m);
- bfs();
- LCA(,n);
- PRT();
- return ;
- }
poj 1986 Distance Queries(LCA:倍增/离线)的更多相关文章
- POJ.1986 Distance Queries ( LCA 倍增 )
POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...
- POJ 1986 Distance Queries LCA两点距离树
标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...
- POJ 1986 Distance Queries(Tarjan离线法求LCA)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12846 Accepted: 4552 ...
- poj 1986 Distance Queries LCA
题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...
- POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]
题目链接:http://poj.org/problem?id=1986 Description Farmer John's cows refused to run in his marathon si ...
- POJ 1986 Distance Queries(LCA Tarjan法)
Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...
- POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)
POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...
- POJ 1986 Distance Queries 【输入YY && LCA(Tarjan离线)】
任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total ...
- poj 1986 Distance Queries(LCA)
Description Farmer John's cows refused to run in his marathon since he chose a path much too long fo ...
- poj 1986 Distance Queries 带权lca 模版题
Distance Queries Description Farmer John's cows refused to run in his marathon since he chose a pa ...
随机推荐
- mysql Host ‘XXXXXX’ is blocked because of many connection errors
mysql Host ‘XXXXXX’ is blocked because of many connection errors ERROR 1129 (00000): Host ‘XXXXXX’ i ...
- 使用静态变量的方法求n!
下面的程序可以输出1-5的阶乘值,如果需要把5改为n,则可求出1-n的阶乘值. void main() { setvbuf(stdout,NULL,_IONBF,); int fac(int n); ...
- Filter及FilterChain的使用详解(转)
一.Filter的介绍及使用 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中.但是与其他web应用程序组件不同的是,过滤器是"链&quo ...
- java Socket用法详解(转)
在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...
- hdu 2196
树形dp 本文出自 http://blog.csdn.net/shuangde800 题目传送门 题意: 给出一棵树,求离每个节点最远的点的距离 思路: 把无根树转化成有根树分析, 对于上面那棵树 ...
- Web App之一
JSP/HTML/CSS---------View(不包含任何的数据,只作为基本的layout) JS------------------------Data(update JSP/HTML)
- object-c 入门基础篇
原地址:http://www.cnblogs.com/moonvan/archive/2011/10/13/2210498.html 一.Objective-C与C的渊源 Objective-C诞生于 ...
- Chp11: Sorting and Searching
Common Sorting Algo: Bubble Sort: Runime: O(n2) average and worst case. Memory: O(1). void BubbleSor ...
- POJ 1666
#include<iostream> using namespace std; int main() { int num_stu; int i; ; do{ time=; cin>& ...
- autocomplete参数说明以及实例
JQuery autocomplete使用手册 Jquery autocomplete是一个很强大的类似google suggest的自动提示插件.它几乎可以满足我们所有的需要. 官方网站:http: ...