hdu 2874 lca-tarjan离线算法(模板)
2015-08-09 20:44
357 查看
题意:
给n个点,m条边带权值的森林,然后q(10^6)次询问,询问每个点之间的最短距离,若两点不属于同一个联通块,则输出not ...
解析:
新学了一种lca-tarjan的模板,看起来稳多了。
这题是遍历所有的点,把森林中的也变成lca。
然后记录答案,最后如果答案被修改过,就输出,如果为-1,则点没有被连到。
代码:
给n个点,m条边带权值的森林,然后q(10^6)次询问,询问每个点之间的最短距离,若两点不属于同一个联通块,则输出not ...
解析:
新学了一种lca-tarjan的模板,看起来稳多了。
这题是遍历所有的点,把森林中的也变成lca。
然后记录答案,最后如果答案被修改过,就输出,如果为-1,则点没有被连到。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <set> #include <climits> #include <cassert> #define Min(a,b) ((a)<(b)?(a):(b)) #define Max(a,b) ((a)>(b)?(a):(b)) #define LL long long #define lson lo, mi, rt << 1 #define rson mi + 1, hi, rt << 1 | 1 using namespace std; const int inf = 0x3f3f3f3f; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); const int maxn = 10000 + 10; const int maxm = 20000 + 10; const int maxq = 2000000 + 10; int n, m, q; int dis[maxn], vis[maxn], ancestor[maxn]; int ans[maxq >> 1]; struct Edge { int to, next; int len; } edge[maxm]; int edgeNum; int edgeHead[maxn]; void addEdge(int fr, int to, int len) { edge[edgeNum].to = to; edge[edgeNum].len = len; edge[edgeNum].next = edgeHead[fr]; edgeHead[fr] = edgeNum++; edge[edgeNum].to = fr; edge[edgeNum].len = len; edge[edgeNum].next = edgeHead[to]; edgeHead[to] = edgeNum++; } struct Query { int to, next; int id; } query[maxq]; int queryNum; int queryHead[maxn]; void addQuery(int fr, int to, int id) { query[queryNum].to = to; query[queryNum].id = id; query[queryNum].next = queryHead[fr]; queryHead[fr] = queryNum++; query[queryNum].to = fr; query[queryNum].id = id; query[queryNum].next = queryHead[to]; queryHead[to] = queryNum++; } int Find(int x) { if (ancestor[x] == x) return x; return ancestor[x] = Find(ancestor[x]); } void lca(int u, int dep, int rt) { ancestor[u] = u; vis[u] = rt; dis[u] = dep; for (int i = edgeHead[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (vis[v] == -1) { lca(v, dep + edge[i].len, rt); ancestor[v] = u; } } for (int i = queryHead[u]; i != -1; i = query[i].next) { int v = query[i].to; if (vis[v] == rt) { //ans[query[i].id] = ancestor[Find(v)] ans[query[i].id] = dis[v] + dis[u] - 2 * dis[Find(v)]; } } } void init() { edgeNum = 0; queryNum = 0; memset(edgeHead, -1, sizeof(edgeHead)); memset(queryHead, -1, sizeof(queryHead)); memset(vis, -1, sizeof(vis)); memset(ans, -1, sizeof(ans)); } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAL while (~scanf("%d%d%d", &n, &m, &q)) { init(); while (m--) { int fr, to, len; scanf("%d%d%d", &fr, &to, &len); addEdge(fr, to, len); } for (int i = 0; i < q; i++) { int fr, to; scanf("%d%d", &fr, &to); ans[i] = -1; addQuery(fr, to, i); } for (int i = 1; i <= n; i++) { if (vis[i] == -1) { lca(i, 0, i); } } for (int i = 0; i < q; i++) { if (ans[i] == -1) { puts("Not connected"); } else { printf("%d\n", ans[i]); } } } return 0; }
相关文章推荐
- HDU 3478
- 第一章 绪论
- 高并发处理方案
- “||”操作符小用
- 队列笔记
- IM-即时通讯技术概述
- HDU 2444
- Android四大组件之三:ContentProvider数据共享
- unbuntu下如何更新adobe flash插件
- IM-即时通讯技术概述
- 协议详解3——IP
- PyQt5初级教程--PyQt5中的拖放[10/13]
- HDU 5366
- 【C/C++学院】0726-cppIDE/一级指针/指针数组/函数指针/函数指针数组/二级指针
- Flatten Binary Tree to Linked List
- Spring注解
- 顿悟,职业生涯最重要的是行业水平的积累,而不是多学某一门语言(很危险)——遥想铁血强人刘志军对铁路行业的理解以及执行力
- 使用Jayrock开源组件创建参数可为空的接口
- Program D--贪心-区间覆盖
- 图片下载缓存防止OOM