离线LCA hdu2586 How far away ?
2015-10-21 15:10
281 查看
传送门:点击打开链接
题意:一棵树,告诉你两个点,求两个点之间的距离
思路:裸LCA。维护点到根节点的距离,那么u到根节点距离+v到根节点距离-lca(u,v)到根节点距离即可
离线LCA的思路很清晰,大概就是利用从下向上的并查集去维护节点。
题意:一棵树,告诉你两个点,求两个点之间的距离
思路:裸LCA。维护点到根节点的距离,那么u到根节点距离+v到根节点距离-lca(u,v)到根节点距离即可
离线LCA的思路很清晰,大概就是利用从下向上的并查集去维护节点。
#include<map> #include<set> #include<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define fuck printf("fuck") #define FIN freopen("input.txt","r",stdin) #define FOUT freopen("output.txt","w+",stdout) using namespace std; typedef long long LL; const int MQ = 40000 + 5; const int MX = 80000 + 5; struct Edge { int v, d; Edge(int _v, int _d) { v = _v; d = _d; } }; struct Que { int id, u, v; Que() {} Que(int _u, int _v, int _id) { u = _u; v = _v; id = _id; } } A[MQ]; int D[MX]; struct LCA { int n, ans[MQ]; int P[MX]; bool vis[MX]; vector<Edge>E[MX]; vector<Que>Q[MQ]; void Init(int _n) { n = _n; memset(ans, -1, sizeof(ans)); memset(vis, false, sizeof(vis)); for(int i = 1; i <= n; i++) { E[i].clear(); Q[i].clear(); P[i] = i; } } void AddQue(int u, int v, int id) { Q[u].push_back(Que(u, v, id)); Q[v].push_back(Que(v, u, id)); } void AddEdge(int u, int v, int d) { E[u].push_back(Edge(v, d)); E[v].push_back(Edge(u, d)); } int Find(int x) { return P[x] == x ? x : (P[x] = Find(P[x])); } void Union(int u, int v) { int p1 = Find(u), p2 = Find(v); P[p1] = p2; } void DFS(int u, int f, int d) { D[u] = d; for(int i = 0; i < E[u].size(); i++) { int v = E[u][i].v, cost = E[u][i].d; if(v != f) DFS(v, u, d + cost); } vis[u] = 1; for(int i = 0; i < Q[u].size(); i++) { int v = Q[u][i].v, id = Q[u][i].id; if(vis[v]) { ans[id] = Find(v); } } Union(u, f); } } lca; int main() { int T, n, m; //FIN; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); lca.Init(n); int u, v, d; for(int i = 1; i <= n - 1; i++) { scanf("%d%d%d", &u, &v, &d); lca.AddEdge(u, v, d); } for(int i = 1; i <= m; i++) { scanf("%d%d", &u, &v); lca.AddQue(u, v, i); A[i] = Que(u, v, i); } lca.DFS(1, 1, 0); for(int i = 1; i <= m; i++) { int u = A[i].u, v = A[i].v, f = lca.ans[i]; printf("%d\n", D[u] + D[v] - 2 * D[f]); } } return 0; }
相关文章推荐
- springMVC 使用jstl
- js中使用jstl中得到的值
- DDoS攻防战(一):概述
- 详解YUV420数据格式
- Neutron命令测试1
- 创建计算字段
- 关于ShareSDK分享的功能
- 张子阳:如何在30岁前年薪超过30万
- JS设置cookie,删除cookie
- 旧文备份:热电偶/热电偶分度表生成
- 使用Jquery+Ajax+Json如何实现分页显示附JAVA+JQuery实现异步分页
- struts2+spring整合框架
- 洛谷:JSOI2008 最大数
- windows下启动mysql服务的命令行启动和手动启动方法
- 旧文备份: 工业网络中单片机节点的地址和波特率设置方式
- 开博啦,加油!!
- 多边形扫面线填充算法
- /proc/sys/net/ipv4/下各文件的作用
- 基地址和偏移地址的概念
- Matlab之switch-case语句