【Lca 离线Tarjan算法】hdu 2586 How far away ?
2017-07-08 22:17
447 查看
LCA 离线Tarjan算法
题意: 对于一个图,n(<=40000)个点,给出n-1条边(u,v,w,), m(<=200)个询问给出两点,问其最短距离。
Tarjan 离线求LCA:
离线算法(必然先存所有询问);
dfs:
1. 遍历到当前点,创造一个当前点的集合
2. 对于遍历完的子树,将其根节点的集合加入其父节点所在的集合。
3. 对于询问的两点,遍历到一点,如果另一点已经被遍历,那么另一点已经加入集合的最高那一点即为最近公共祖先。
4. 因为另一点可能在此点的子树上,所以询问的答案应该在遍历完其子树后执行。
注意: 问题的记录最好用前向星写吧。
题意: 对于一个图,n(<=40000)个点,给出n-1条边(u,v,w,), m(<=200)个询问给出两点,问其最短距离。
Tarjan 离线求LCA:
离线算法(必然先存所有询问);
dfs:
1. 遍历到当前点,创造一个当前点的集合
2. 对于遍历完的子树,将其根节点的集合加入其父节点所在的集合。
3. 对于询问的两点,遍历到一点,如果另一点已经被遍历,那么另一点已经加入集合的最高那一点即为最近公共祖先。
4. 因为另一点可能在此点的子树上,所以询问的答案应该在遍历完其子树后执行。
注意: 问题的记录最好用前向星写吧。
#include<bits/stdc++.h> using namespace std; typedef long long LL; //#pragma comment(linker, "/STACK:102400000,102400000") const double PI = acos(-1.0); const double eps = 1e-6; const int INF=0x3f3f3f3f; const LL mod = 1e9+7; const int N = 100000+10; const int M = 2500000; struct Node { int from; int to; int val; int next; }; int dir ,fa ,vis ; vector<Node> ma ; //vector 记录图 Node query[N*2]; int head ; int ans ; void addquery(int u,int v,int &top) { query[++top].from = u; query[top].to = v; query[top].next = head[u]; head[u] = top; query[++top].from = v; query[top].to = u; query[top].next = head[v]; head[v] = top; } int Find(int n) { if(fa != n){ fa = Find(fa ); } return fa ; } void dfs(int n,int dist) //dfs处理需要数组 { fa = n; vis =true; dir =dist; for(int i = 0; i < ma .size(); i++){ Node temp = ma [i]; if(!vis[temp.to]){ dfs(temp.to,dist+temp.val); fa[temp.to] = n; } } for(int i = head ; i != -1; i=query[i].next){ int v = query[i].to; if(vis[v]){ int pa = Find(v); //query[i].val = dir +dir[v]-2*dir[pa]; ans[(i-1)/2] = dir +dir[v]-2*dir[pa]; } } } int main() { int T; scanf("%d",&T); while(T--){ memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); int n,m; scanf("%d%d",&n,&m); for(int i = 1; i <= n; i++){ ma[i].clear(); } for(int i = 1; i < n; i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); Node temp; temp.to = v; temp.val = w; ma[u].push_back(temp); temp.to = u; temp.val = w; ma[v].push_back(temp); } int top = 0; for(int i = 0; i < m; i++){ int u,v; scanf("%d%d",&u,&v); addquery(u,v,top); } dfs(1,0); for(int i = 0; i < m; i++){ printf("%d\n",ans[i]); } } return 0; }
相关文章推荐
- HDU 2586 How far away ? (离线LCA Tarjan算法模板)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- HDU 2586 How far away ? LCA离线tarjan思想
- HDU 2586 How far away ? tarjan算法求LCA
- hdu-2586-How far away ?(离线LCA)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- HDU - 2586 How far away ?(离线Tarjan算法)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ? (LCA 离线tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)
- HDU - 2586 How far away ?(tarjan离线做法求lca)
- HDU 2586 How far away ? (LCA模板题 Tarjan算法求最小公共祖先)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- HDU - 2586 How far away ?(LCA tarjan离线做法)