hdu - 2586 How far away ?(最短路共同祖先问题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
最近公共祖先问题~~LAC离散算法
题目大意:一个村子里有n个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问两个房子a,b之间的距离是多少。
很明显的最近公共祖先问题,先建一棵树,然后求出每一点i到树根的距离dis[i],然后每次询问a,b之间的距离=dis[a]+dis[b]-2*dis[LCA(a,b)];
LCA(a,b)即是a,b的最近公共祖先。。
关于最近公共祖先,给大家推荐一个学长的博客http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html,里面讲的很不错!!
- # include<stdio.h>
- # include<string.h>
- # define N
- # define M
- struct node{
- int from,to,next,val;
- }edge[*N];
- struct node1{
- int from,to,next,num;
- }edge1[*M];
- int tol,head[N],head1[N],tol1,father[N],dis[N],LCA[M],n,m;
- bool visit[N];
- void add(int a,int b,int c)
- {
- edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];edge[tol].val=c;head[a]=tol++;
- }
- void add1(int a,int b,int c)
- {
- edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];edge1[tol1].num=c;head1[a]=tol1++;
- }
- int find(int x)
- {
- if(x!=father[x])
- father[x]=find(father[x]);
- return father[x];
- }
- void tarjan(int u)
- {
- int j,v;
- visit[u]=;
- father[u]=u;
- //////////////////
- for(j=head1[u];j!=-;j=edge1[j].next)
- {
- v=edge1[j].to;
- if(visit[v]) LCA[edge1[j].num]=find(v);
- }
- //////////////////
- for(j=head[u];j!=-;j=edge[j].next)
- {
- v=edge[j].to;
- if(!visit[v])
- {
- dis[v]=dis[u]+edge[j].val;
- tarjan(v);
- father[v]=u;
- }
- }
- }
- int main()
- {
- int i,ncase,a,b,c;
- scanf("%d",&ncase);
- while(ncase--)
- {
- scanf("%d%d",&n,&m);
- tol=;
- memset(head,-,sizeof(head));
- for(i=;i<n;i++)
- {
- scanf("%d%d%d",&a,&b,&c);
- add(a,b,c);
- add(b,a,c);
- }
- memset(visit,,sizeof(visit));
- tol1=;
- memset(head1,-,sizeof(head1));
- for(i=;i<=m;i++)
- {
- scanf("%d%d",&a,&b);
- add1(a,b,i);
- add1(b,a,i);
- }
- ///LCA是一种离线算法,所以刚开始需要把所有的询问都输入,然后用邻接表进行存储,i表示第i次询问
- dis[]=;
- tarjan();
- for(i=;i<tol1;i+=)
- {
- a=edge1[i].from;
- b=edge1[i].to;
- c=edge1[i].num;
- printf("%d\n",dis[a]+dis[b]-*dis[LCA[c]]);
- }
- }
- return ;
- }
**************************
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <vector>
- using namespace std;
- const int NN=;
- int n,m;
- vector<pair<int,int> > edge[NN],qe[NN];
- vector<int> q1,q2;
- int p[NN];
- int find(int x)
- {
- if (p[x]!=x) p[x]=find(p[x]);
- return p[x];
- }
- int sum=,ans[NN],dis[NN];
- bool vis[NN]={};
- void lca(int u,int fa)
- {
- p[u]=u;
- for (int i=; i<edge[u].size(); i++)
- {
- int v=edge[u][i].first;
- if (v==fa) continue;
- dis[v]=dis[u]+edge[u][i].second;
- lca(v,u);
- p[v]=u;
- }
- vis[u]=true;
- if (sum==m) return;
- for (int i=; i<qe[u].size(); i++)
- {
- int v=qe[u][i].first;
- if (vis[v])
- ans[qe[u][i].second]=dis[u]+dis[v]-*dis[find(v)];
- }
- }
- int main()
- {
- int u,v,w;
- int t;
- scanf("%d",&t);
- while(t--){
- scanf("%d%d",&n,&m);
- for (int i=; i<=n; i++)
- {
- edge[i].clear();
- }
- for (int i=; i<n; i++)
- {
- scanf("%d%d%d",&u,&v,&w);
- edge[u].push_back(make_pair(v,w));
- edge[v].push_back(make_pair(u,w));
- }
- for (int i=; i<m; i++)
- {
- scanf("%d%d",&u,&v);
- qe[u].push_back(make_pair(v,i));
- qe[v].push_back(make_pair(u,i));
- ans[i]=;
- }
- dis[]=;
- lca(,);
- for (int i=; i<m; i++) printf("%d\n",ans[i]);
- }
- return ;
- }
hdu - 2586 How far away ?(最短路共同祖先问题)的更多相关文章
- HDU - 2586 How far away ?(LCA模板题)
HDU - 2586 How far away ? Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- LCA(最近公共祖先)--tarjan离线算法 hdu 2586
HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- hdu 2586(最近公共祖先LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...
- HDU 2586 How far away? LCA 转化成RMQ
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分 ...
- HDU 2586
http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:求最近祖先节点的权值和 思路:LCA Tarjan算法 #include <stdio.h&g ...
- hdu 2586 How far away
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) T ...
- HDU 2586 (LCA模板题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 / \ 2 3 ...
- HDU 5637 Transform 单源最短路
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5637 题意: http://bestcoder.hdu.edu.cn/contests/contes ...
随机推荐
- css3部分属性兼容性别扭写法(因为很多我就叫他别扭了,希望全面早早支持css3吧)
/*圆角class,需要设置圆角的元素加上class名称*/ .roundedCorners{ -webkit-border-radius: 10px;/*webkit内核浏览器*/ -moz-bor ...
- DataTable Javascript Link not working on 2nd page
$(document).ready(function () { var otable = $('#tbl-resources').dataTable( { bJQueryUI: false, bFil ...
- windows xp sp3 下载地址
windows xp service pack 3/ windows xp sp3 简体中文版下载地址: http://download.windowsupdate.com/msdownload/ ...
- WCF部署在IIS上
WCF部署在IIS上 环境vs2010,WCF应用程序.如何将WCF部署在IIS上. 第一步:右键点击项目,选择生成部署包. 第二步:在你项目所在的文件目录下找到Package文件夹,这就是我们的部署 ...
- YaHoo Web优化的14条法则
Web应用性能优化黄金法则:先优化前端程序(front-end)的性能,因为这是80%或以上的最终用户响应时间的花费所在. 法则1. 减少HTTP请求次数 80%的最终用户响应时间花在前端程序上,而其 ...
- C#中几种数据库的大数据批量插入
C#语言中对SqlServer.Oracle.SQLite和MySql中的数据批量插入是支持的,不过Oracle需要使用Orace.DataAccess驱动. IProvider里有一个用于实现批量插 ...
- json处理三部曲之第二曲:利用Jackson处理json
利用Jackson处理json需要导入的jar包(2以上版本的): <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.c ...
- NEU OJ 1644 Median I
优先级队列 #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> ...
- 编译cvaux错误的原因
引用: http://www.cnblogs.com/oskycar/archive/2009/08/30/1556920.html VS2013 在debug模式下编译cvaux时会提示三个错误 ...
- POJ 1611 The Suspects(简单并查集)
( ̄▽ ̄)" #include<iostream> #include<cstdio> using namespace std; ]; void makeSet(int ...