How far away ? HDU - 2586 tarjan求LCA
2017-10-03 00:55
369 查看
题意:给你n个村庄,n-1条路将所有村庄联通,每条路都有自己的长度。m次提问,问a,b村庄之间路的长度。
分析:这个就是在一棵树上求两个点的距离嘛。LCA。因为数据范围比较小,暴力的话,每组时间复杂度为m*q,可以卡过去。
用Tarjan的话,每组时间复杂度为m+q,用Tarjan求LCA是一种离线做法,先把所有询问都存起来,然后相同起点的可以一起算。
d[i]:从根到i点的距离
f[i]:i的祖先
vis[i]:标记数组
edge[i]:存边
q[i]:存询问
col[i]:标记目前哪些点可以直接查找
主要的是并查集的使用~妙呀~
(PE是什么鬼,OUTPUT中说每组样例结束后空一行嘛,空了PE。。。不空A了。。
分析:这个就是在一棵树上求两个点的距离嘛。LCA。因为数据范围比较小,暴力的话,每组时间复杂度为m*q,可以卡过去。
用Tarjan的话,每组时间复杂度为m+q,用Tarjan求LCA是一种离线做法,先把所有询问都存起来,然后相同起点的可以一起算。
d[i]:从根到i点的距离
f[i]:i的祖先
vis[i]:标记数组
edge[i]:存边
q[i]:存询问
col[i]:标记目前哪些点可以直接查找
主要的是并查集的使用~妙呀~
(PE是什么鬼,OUTPUT中说每组样例结束后空一行嘛,空了PE。。。不空A了。。
#include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <vector> #include <set> #include <map> using namespace std; #define ll long long #define mem(a,b) memset(a,b,sizeof(a)) const int maxn = 4e4+10; struct node { int to,pre,id,v; }edge[maxn*2]; node q[maxn]; int f[maxn],head[maxn],hq[maxn],vis[maxn],col[maxn]; ll ans[maxn],d[maxn]; void init(int n) { mem(edge,0);mem(vis,0);mem(head,-1);mem(hq,-1);mem(q,0);mem(col,0);mem(d,0); for(int i=1;i<=n;i++) f[i]=i; } int h=0; void addedge(int from,int to,int v,int id) { edge[h].to=to;edge[h].v=v;edge[h].id=id;edge[h].pre=head[from]; head[from]=h; } void addq(int from,int to,int v,int id) { q[h].to=to;q[h].v=v;q[h].id=id;q[h].pre=hq[from]; hq[from]=h; } void dfs(int u,int val) { d[u]=val; for(int i=head[u];i>-1;i=edge[i].pre) { int v=edge[i].to; if(!vis[v]) { vis[v]=1; dfs(v,val+edge[i].v); } } } int getf(int k) { if(k==f[k]) return k; else return f[k]=getf(f[k]); } void uin(int a,int b) { int x=getf(a),y=getf(b); if(x!=y) f[y]=x; } void Tarjan(int u) { for(int i=head[u];i>-1;i=edge[i].pre) { node e=edge[i]; if(!vis[e.to]) { vis[e.to]=1; Tarjan(e.to); uin(u,e.to); } } col[u]=1; for(int i=hq[u];i>-1;i=q[i].pre) { node e=q[i]; if(!col[e.to]) continue; ans[e.id]=d[u]+d[e.to]-2*d[f[getf(e.to)]];//不能直接f[e.to],因为这里确保是最上面的祖先,因为uin的时候f[y]=x,但是以y为爸爸的孩子们的爸爸还没有改到x~ } } int main() { int T; scanf("%d",&T); while(T--) { int n,m; h=0; scanf("%d %d",&n,&m); init(n); for(int i=0;i<n-1;i++) { int a,b,k; scanf("%d %d %d",&a,&b,&k); addedge(a,b,k,i);h++;addedge(b,a,k,i);h++; } vis[1]=1; dfs(1,0);h=0; for(int i=1;i<=m;i++) { int a,b; scanf("%d %d",&a,&b); addq(a,b,0,i);h++;addq(b,a,0,i);h++; } memset(vis,0,sizeof(vis));vis[1]=1; Tarjan(1); for(int i=1;i<=m;i++) { printf("%I64d\n",ans[i]); } // printf("\n"); } 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? LCA 离线tarjan
- How far away ? HDU - 2586 tarjan求LCA
- HDU - 2586 How far away ?(tarjan离线做法求lca)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- How far away ? HDU - 2586 tarjan求LCA
- HDU-2586 How far away ? LCA-Tarjan Or spfa
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- How far away ? HDU - 2586 tarjan求LCA
- HDU 2586 How far away ? (LCA,Tarjan, spfa)
- HDU2586 How far away ?(最近公共祖先lca,离线Tarjan,最短路)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- How far away ? HDU - 2586 tarjan求LCA
- hdu 2586 How far away ? (LCA 离线tarjan)
- hdu 2586 How far away ?(在线LCA+离线Tarjan)
- How far away ? HDU - 2586 tarjan求LCA
- hdu 2586 How far away ?(在线LCA+离线Tarjan)