poj1986 Distance Queries(LCA)
2016-09-01 19:41
337 查看
带权重 每条边 求两个点之间权重
如果确定根为1,则有Dist(u,v) = Dist(1,u) + Dist(1,v) - 2*Dist( 1,LCA(u,v) )。
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
如果确定根为1,则有Dist(u,v) = Dist(1,u) + Dist(1,v) - 2*Dist( 1,LCA(u,v) )。
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
#include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <algorithm> using namespace std; const int maxn = 80080; const int quest = 20020; int pre[maxn], head[maxn], qhead[maxn], dist[maxn]; struct node{ int to; int next; int lca;}edge[maxn]; node q[maxn]; int finn(int x) { while(x != pre[x]) { x = pre[x]; } return x; } bool vis[maxn]; void LCA(int u) { pre[u] = u; vis[u] = true; for(int k = head[u]; k != -1; k = edge[k].next) { if(!vis[edge[k].to]) { dist[edge[k].to] = dist[u] + edge[k].lca; LCA(edge[k].to); pre[edge[k].to] = u; } } for(int k = qhead[u]; k != -1; k = q[k].next) { if(vis[q[k].to]) { q[k].lca = dist[u] + dist[q[k].to] - 2 * dist[finn(q[k].to)]; q[k^1].lca = q[k].lca; } } } int main() { int n, m, k, u, v, w, a, b; char s; while(~scanf("%d%d", &n, &m)) { memset(head, -1, sizeof(head)); memset(qhead, -1, sizeof(qhead)); memset(vis, false, sizeof(vis)); memset(edge, 0, sizeof(edge)); memset(q, 0, sizeof(q)); memset(dist, 0, sizeof(dist)); int id = 0; for(int i = 0; i < m; i++) { scanf("%d%d%d %c", &u, &v, &w, &s); edge[id].to = v; edge[id].lca = w; edge[id].next = head[u]; head[u] = id++; edge[id].to = u; edge[id].lca = w; edge[id].next = head[v]; head[v] = id++; } scanf("%d", &k); int iq = 0; for(int i = 0; i < k; i++) { scanf("%d%d", &a, &b); q[iq].to = b; q[iq].next = qhead[a]; qhead[a] = iq++; q[iq].to = a; q[iq].next = qhead[b]; qhead[b] = iq++; } LCA(1); for(int i = 0; i < iq; i+= 2) { printf("%d\n", q[i].lca); } } }
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> using namespace std; const int maxn = 100010; int n, m, k; int ancestor[maxn]; int pre[maxn]; int first[maxn]; int next[maxn]; int dis[maxn]; int vis[maxn]; vector<int> v[maxn]; struct node{ int x; int y; int value; int ans;}e[maxn], q[maxn];//保存读入边和询问边 void init() { for(int i = 1; i <= n; i++) { pre[i] = i; v[i].clear(); } memset(ancestor, 0, sizeof(ancestor)); memset(first, -1, sizeof(first)); memset(next, -1, sizeof(next)); memset(dis, 0, sizeof(dis)); memset(vis, 0, sizeof(vis)); } /* int finn(int x) { if(x != pre[x]) { pre[x] = finn(pre[x]); } return pre[x]; } */ int finn(int x) { int z, y = x; while(y != pre[y]) { y = pre[y]; } while(x != pre[x]) { z = pre[x]; pre[x] = y; x = z; } return y; } void join(int x, int y) { x = finn(x); y = finn(y); pre[x] = y; } void LCA(int u) { ancestor[u] = u; vis[u] = 1;//标记为处理过 for(int i = first[u]; i != -1; i = next[i]) { if(!vis[e[i].y])//找到没被处理的点 { dis[e[i].y] = dis[u] + e[i].value;//更新dis数组 LCA(e[i].y);//继续搜索子树 join(e[i].y,u);//合并 ancestor[finn(e[i].y)] = u; //当前节点为子树的祖先 } } //处理u和v[u][i]有关的询问 for(int i = 0; i < v[u].size(); i++) { if(vis[v[u][i]]) { for(int j = 0; j < k; j++) { if(q[j].x == u && q[j].y == v[u][i] || q[j].x == v[u][i] && q[j].y == u) { q[j].ans = pre[finn(v[u][i])]; } } } } } int main() { char c; while(scanf("%d%d", &n, &m) != EOF) { init(); for(int i = 0; i < m; i++) { scanf("%d %d %d %c" , &e[i].x , &e[i].y , &e[i].value , &c); //邻接表存储无向图 e[i + m].x = e[i].y; e[i + m].y = e[i].x; e[i + m].value = e[i].value; next[i] = first[e[i].x]; first[e[i].x] = i; next[i + m] = first[e[i + m].x]; first[e[i + m].x] = i + m; } scanf("%d", &k); for(int i = 0; i < k; i++) { scanf("%d%d", &q[i].x, &q[i].y); v[q[i].x].push_back(q[i].y); v[q[i].y].push_back(q[i].x); } LCA(1);//1作为根节点求lca for(int i = 0; i < k; i++) { int tmp = dis[q[i].x] + dis[q[i].y] - 2 * dis[q[i].ans]; printf("%d\n", tmp); } } return 0; }
相关文章推荐
- POJ 1986 Distance Queries(求最近公共祖先,LCA-Tarjan)
- POJ 1986 Distance Queries(LCA)
- POJ 1986 Distance Queries (在线LCA转RMQ)
- poj 1986 Distance Queries 【LCA转RMQ 裸题】【求两点最短距离】
- POJ1986:Distance Queries(LCA求距离 + Tarjan)
- POJ---1986-Distance Queries(LCA-Tarjan)
- POJ 1986 LCA,tarjan实现
- POJ 1986 Distance Queries LCA
- POJ 1986 Distance Queries(LCA Tarjan离线算法)
- poj 1986 Distance Queries (LCA)
- POJ 1986 RMQ+LCA
- POJ1986-Distance Queries(LCA)
- 【RMQ+LCA】POJ 1986
- POJ1986 Distance Queries(树链剖分LCA)
- Distance Queries - POJ 1986 LCA
- POJ 1986 Distance Queries [LCA]
- poj 1986LCA离线dfs+并查集
- poj 1986 Distance Queries 离线LCA
- Poj 1986 Distance Queries (LCA 树上两点间最短距离)
- POJ 1986 Distance Queries LCA和RMQ