HDU - 2586 How far away ?(离线Tarjan算法)
2015-11-13 23:21
393 查看
1、给定一棵树,每条边都有一定的权值,q次询问,每次询问某两点间的距离。
2、这样就可以用LCA来解,首先找到u, v 两点的lca,然后计算一下距离值就可以了。
这里的计算方法是,记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - 2 * dis[lca(u, v)]
3、
View Code
2、这样就可以用LCA来解,首先找到u, v 两点的lca,然后计算一下距离值就可以了。
这里的计算方法是,记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - 2 * dis[lca(u, v)]
3、
/* 离线算法,LCATarjan 复杂度O(n+Q); */ #include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int MAXN=40005; const int MAXQ=205;//查询数的最大值 int dis[MAXN];//到根节点的距离 //并查集部分 int F[MAXN];//需要初始化为-1 int find(int x){ if(F[x]==-1)return x; return F[x]=find(F[x]); } void bing(int u,int v){ int t1=find(u); int t2=find(v); if(t1!=t2) F[t1]=t2; } //*********************** bool vis[MAXN];//访问标记 int ancestor[MAXN];//祖先 struct Edge{ int to,next; int d; }edge[MAXN*2]; int head[MAXN],tot; void addedge(int u,int v,int d){ edge[tot].to=v; edge[tot].d=d; edge[tot].next=head[u]; head[u]=tot++; } struct Query{ int q,next; int index;//查询编号 }query[MAXQ*2]; int answer[MAXQ];//存储最后的查询结果,下标0 Q-1 int h[MAXN];//注意此处为MAXN... int tt; void add_query(int u,int v,int index){ query[tt].q=v; query[tt].next=h[u]; query[tt].index=index; h[u]=tt++; query[tt].q=u; query[tt].next=h[v]; query[tt].index=index; h[v]=tt++; } void init(){ tot=0; memset(head,-1,sizeof(head)); tt=0; memset(h,-1,sizeof(h)); memset(vis,false,sizeof(vis)); memset(F,-1,sizeof(F)); memset(ancestor,0,sizeof(ancestor)); } void LCA(int u){ ancestor[u]=u; vis[u]=true; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].to; if(vis[v])continue; dis[v]=dis[u]+edge[i].d; LCA(v); bing(u,v); ancestor[find(u)]=u; } for(int i=h[u];i!=-1;i=query[i].next){ int v=query[i].q; if(vis[v]){ answer[query[i].index]=ancestor[find(v)]; } } } int main(){ int T; int n,m; int i; int u,v,d; scanf("%d",&T); while(T--){ init(); scanf("%d%d",&n,&m); for(i=0;i<n-1;++i){ scanf("%d%d%d",&u,&v,&d); addedge(u,v,d); addedge(v,u,d); } for(i=0;i<m;++i){ scanf("%d%d",&u,&v); add_query(u,v,i); } dis[1]=0; LCA(1); for(i=0;i<m;++i){ printf("%d\n",dis[query[i*2].q]+dis[query[i*2+1].q]-2*dis[answer[i]]); } } return 0; }
View Code
相关文章推荐
- 开发体验心得总结
- 《易货》Alpha版本测试报告
- C 如何拼接字符串
- struts.xml配置详解
- Hadoop学习路线图
- 个人阅读作业week7
- 个人阅读作业Week5
- Android完整的app项目
- Android按下返回键后,程序不退出,进入后台运行。使用moveTaskToBack(boolean nonRoot)
- 某一常见电脑病毒的剖析
- Android消息机制
- css相对定位绝对定位和内容居中详解
- 读面向业务的立体化高可用架构总结
- 数据的交换输出
- struts2中使用到的一部分jar包
- PASCAL的优越性:官方的说法(不需要Makefile,节约大量的时间)
- Java finally语句到底是在return之前还是之后执行?
- 数塔问题
- 安装Exchange Server2016管理工具
- Basic Calculator