POJ1986(LCA应用:求两结点之间距离)
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 11304 | Accepted: 3985 | |
Case Time Limit: 1000MS |
Description
Input
* Line 2+M: A single integer, K. 1 <= K <= 10,000
* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.
Output
Sample Input
- 7 6
- 1 6 13 E
- 6 3 9 E
- 3 5 7 S
- 4 1 3 N
- 2 4 20 W
- 4 7 2 S
- 3
- 1 6
- 1 4
- 2 6
Sample Output
- 13
- 3
- 36
学习LCA的好文章:http://taop.marchtea.com/04.04.html
离线:将所有查询输入完毕后再统一输出结果。
在线:查询一个输出一个。- dfs+并查集,离线
- #include <cstdio>
- #include <vector>
- using namespace std;
- const int MAXN=;
- int n,m,k;
- struct Edge{
- int to,w;
- Edge(){}
- Edge(int to,int w)
- {
- this->to=to;
- this->w=w;
- }
- };
- vector<Edge> arc[MAXN];
- struct Node{
- int to,id;
- Node(){}
- Node(int to,int id)
- {
- this->to=to;
- this->id=id;
- }
- };
- vector<Node> que[MAXN];
- int par[MAXN];
- void prep()
- {
- for(int i=;i<MAXN;i++)
- {
- d[i]=;
- vis[i]=;
- par[i]=i;
- }
- }
- int fnd(int x)
- {
- if(par[x]==x)
- {
- return x;
- }
- return par[x]=fnd(par[x]);
- }
- void unite(int fa,int son)
- {
- int a=fnd(fa);
- int b=fnd(son);
- par[b]=a;
- }
- int vis[MAXN],d[MAXN];
- int res[MAXN];
- void tarjan(int u)
- {
- vis[u]=;
- for(int i=,size=que[u].size();i<size;i++)
- {
- Node nod=que[u][i];
- if(vis[nod.to])
- {
- int lca=fnd(nod.to);
- res[nod.id]=d[nod.to]+d[u]-*d[lca];
- }
- }
- for(int i=,size=arc[u].size();i<size;i++)
- {
- Edge e=arc[u][i];
- if(!vis[e.to])
- {
- d[e.to]=d[u]+e.w;
- tarjan(e.to);
- unite(u,e.to);
- }
- }
- }
- int main()
- {
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- prep();
- for(int i=;i<=n;i++) arc[i].clear();
- for(int i=;i<m;i++)
- {
- int u,v,w;
- scanf("%d %d %d %*c",&u,&v,&w);
- arc[u].push_back(Edge(v,w));
- arc[v].push_back(Edge(u,w));
- }
- scanf("%d",&k);
- for(int i=;i<k;i++)
- {
- int u,v;
- scanf("%d%d",&u,&v);
- que[v].push_back(Node(u,i));
- que[u].push_back(Node(v,i));
- }
- for(int i=;i<=n;i++)
- {
- if(!vis[i])
- {
- tarjan(i);
- }
- }
- for(int i=;i<k;i++)
- {
- printf("%d\n",res[i]);
- }
- }
- return ;
- }
- 模板:RMQ求LCA在线算法(稀疏表实现RMQ)
- #include <cstdio>
- #include <cstring>
- #include <vector>
- #include <math.h>
- #include <algorithm>
- using namespace std;
- const int MAXN=;
- int n,m,k;
- struct Edge{
- int to,w;
- Edge(){}
- Edge(int to,int w)
- {
- this->to=to;
- this->w=w;
- }
- };
- vector<Edge> arc[MAXN];
- int vs[MAXN+MAXN],depth[MAXN+MAXN],first[MAXN],tot;
- int d[MAXN],vis[MAXN];
- void dfs(int u,int dep)
- {
- vis[u]=;
- vs[++tot]=u;
- depth[tot]=dep;
- first[u]=tot;
- for(int i=,size=arc[u].size();i<size;i++)
- {
- Edge e=arc[u][i];
- if(!vis[e.to])
- {
- d[e.to]=d[u]+e.w;
- dfs(e.to,dep+);
- vs[++tot]=u;
- depth[tot]=dep;
- }
- }
- }
- int dp[MAXN+MAXN][];
- void init_st(int size)
- {
- for(int i=;i<=size;i++) dp[i][]=i;
- for(int j=;j<;j++)
- {
- for(int i=;i<=size;i++)
- {
- if(i+(<<j)-<=size)
- {
- int a=dp[i][j-];
- int b=dp[i+(<<(j-))][j-];
- dp[i][j]=depth[a]<depth[b]?a:b;
- }
- }
- }
- }
- int rmq_st(int l,int r)
- {
- int limit=(int)(log(r-l+1.0)/(log(2.0)));
- int a=dp[l][limit];
- int b=dp[r-(<<limit)+][limit];
- return depth[a]<depth[b]?a:b;
- }
- int LCA(int u,int v)
- {
- if(first[u]>first[v]) swap(u,v);
- int id=rmq_st(first[u],first[v]);
- return vs[id];
- }
- int main()
- {
- while(scanf("%d%d",&n,&m)!=EOF)
- {
- tot=;
- memset(vis,,sizeof(vis));
- memset(d,,sizeof(d));
- for(int i=;i<=n;i++) arc[i].clear();
- for(int i=;i<m;i++)
- {
- int u,v,w;
- scanf("%d %d %d %*c",&u,&v,&w);
- arc[u].push_back(Edge(v,w));
- arc[v].push_back(Edge(u,w));
- }
- for(int i=;i<=n;i++)
- {
- if(!vis[i])
- {
- dfs(i,);
- }
- }
- init_st(tot);
- scanf("%d",&k);
- for(int i=;i<k;i++)
- {
- int u,v;
- scanf("%d%d",&u,&v);
- int lca=LCA(u,v);
- int res=d[u]+d[v]-*d[lca];
- printf("%d\n",res);
- }
- }
- return ;
- }
POJ1986(LCA应用:求两结点之间距离)的更多相关文章
- hdoj 1869 六度分离【最短路径求两两边之间最长边】
六度分离 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 求两个数之间的质数 -----------基于for循环 算法思想
前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...
- js求连个数之间的数字
整理出自项目中一个需求,求两个数之间的数字. const week = function(arr,arr2){ let a=parseInt(arr); let b=parseInt(arr2); l ...
- 「POJ-3608」Bridge Across Islands (旋转卡壳--求两凸包距离)
题目链接 POJ-3608 Bridge Across Islands 题意 依次按逆时针方向给出凸包,在两个凸包小岛之间造桥,求最小距离. 题解 旋转卡壳的应用之一:求两凸包的最近距离. 找到凸包 ...
- 求两点之间距离 C++
求两点之间距离(20 分) 定义一个Point类,有两个数据成员:x和y, 分别代表x坐标和y坐标,并有若干成员函数. 定义一个函数Distance(), 用于求两点之间的距离.输入格式: 输入有两行 ...
- 旋转卡壳求两个凸包最近距离poj3608
#include <iostream> #include <cmath> #include <vector> #include <string.h> # ...
- JavaScript求两个数字之间所有数字的和
这是在fcc上的中级算法中的第一题,拉出来的原因并不是因为有什么好说的,而是我刚看时以为是求两个数字的和, 很显然错了.我感觉自己的文字理解能力被严重鄙视了- -.故拉出来折腾折腾. 要求: 给你一个 ...
- GPS(2)关于位置的3个示例,实时获取GPS定位数据,求两个经纬点距离,邻近某个区域圆时警告
实时获取GPS定位数据 import android.app.Activity; import android.content.Context; import android.location.Loc ...
- js 求两个日期之间相差天数
//求两个日期之间的相差天数 function daysBetween(DateOne, DateTwo) { var OneMonth = DateOne.substring(5, DateOne. ...
随机推荐
- JavaScript--基于对象的脚本语言学习笔记(一)
1.两种嵌入js的方式 使用javascript前缀构建url:<a href="javascript:alert('执行JavaScript. .')">执行j ...
- web翻译——插件
很多时候,可能我们web项目中需要的只是机械式的翻译,并不需要什么利用xml或者js json等等实现逼真翻译,那样工作量太大.这时候可能你就需要这几款小工具来帮助你.当然,如果 对翻译或者你的项目外 ...
- hdu 5538 House Building(长春现场赛——水题)
题目链接:acm.hdu.edu.cn/showproblem.php?pid=5538 House Building Time Limit: 2000/1000 MS (Java/Others) ...
- programming review (c++): (3)graph, binary search
I.graph #include <iostream> #include <vector> using namespace std; vector<vector<, ...
- java jdbc 同时操作查询删除操作
Connection conn = null; try { // 创建连接实例 conn = JdbcUtility.GetFactory() ...
- 关于eclipse 插件的挂载
学习java的时候,不喜欢myeclipse 这种插件,什么都准备好了,自己动手就少了,不利于自己学习,现在我就diy 自己选几个插件来用,基本上就是 eclipse 加上我自己要用的插件,插件的安装 ...
- 【网络与系统安全】20179209 利用metasploit对windows系统的渗透
这次实验的主角是素有"内网杀手"之称的metasploit.还是少说一些夸赞它的话(因为即使功能再强大,不明白它的原理,不会灵活使用它集成的功能,一样没有用),我们直入主题.简单说 ...
- JavaScript演示如何访问Search字段
<!DOCTYPE html> <html> <body> <h3>演示如何访问Search字段</h3> <input type=& ...
- PHP Framework
PHP Framework is built for PHP developers who need elegant toolkit to create full-featured web appli ...
- Java基础教程:多线程基础(4)——Lock的使用
Java基础教程:多线程基础(4)——Lock的使用 快速开始 Java 5中Lock对象的也能实现同步的效果,而且在使用上更加方便. 本节重点的2个知识点是:ReentrantLock类的使用和Re ...