poj 1986——Distance Queries
来源:互联网 发布:因特网属于什么网络 编辑:程序博客网 时间:2024/06/01 08:18
题意:求树上两点间距离
思路:LCA。用来测试LCA的模板~
用DP维护:
#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>#include<map>#include<set>#include<list>#include<stack>#include<algorithm>#include<queue>#include<vector>#include<time.h>#include<iomanip>#include<assert.h>using namespace std;const int maxn = 100005;struct Edge{ int u,v,w; int id; int next;}edge[maxn*2];int tot ;int first[maxn];void add(int uu,int vv,int ww,int id){ edge[tot].u = uu; edge[tot].v = vv; edge[tot].w = ww; edge[tot].id = id; edge[tot].next = first[uu]; first[uu] = tot++;}int n,m;int dep[maxn];int pre[maxn];int dp[17][maxn];int q[maxn],qh,qt;int recE[maxn];int recN[maxn];int dis[maxn];void bfs(int u) { qh = qt = 0; q[qt ++] = u; for (int j = 0; j < 17; ++ j) dp[j][0] = -1; dep[u] = 0; dis[0] = 0; pre[u] = -1; while (qh != qt) { u = q[qh ++]; for (int now = first[u], v; now != -1; now = edge[now].next) if (dp[0][u] != (v = edge[now].v)) { dp[0][v] = u; for (int j = 1; j < 17; ++ j) { if (dp[j - 1][v] == -1) { dp[j][v] = -1; } else { dp[j][v] = dp[j - 1][dp[j - 1][v]]; } } q[qt ++] = v; dep[v] = dep[u] + 1; pre[v] = edge[now].id; dis[v] = dis[u] + edge[now].w; } }}int lca(int u, int v) { if (dep[u] < dep[v]) swap(u, v); int del = dep[u] - dep[v]; for (int j = 16; j >= 0; -- j) if (del >> j & 1) u = dp[j][u]; for (int j = 16; j >= 0; -- j) if (dp[j][u] != dp[j][v]) { u = dp[j][u]; v = dp[j][v]; } if (u != v) u = dp[0][u]; return u;}inline bool scan_d(int &ret){ char c;int sgn; if(c = getchar(),c == EOF)return 0; while(c!='-' && (c<'0'||c>'9'))c = getchar(); sgn = (c == '-')?-1:1; ret = (c == '-')?0 :c-'0'; while(c = getchar(),c>='0'&&c<='9')ret = ret*10 + (c-'0'); ret *=sgn; return 1;}int col[maxn];void putint(int x){ if(x<0){putchar('-'); x *= -1;} if(x == 0){ putchar('0'); return; } char s[20]; int cur = 0; while(x!=0){ s[cur++] = '0' + x%10; x/=10; } for(int i = cur-1;i>=0;i--){ putchar(s[i]); }}int main(){// freopen("data.txt","r",stdin); tot = 0;memset(first,-1,sizeof(first)); scan_d(n);scan_d(m); for(int i = 0; i < n-1;++i){ int u,v,w; scan_d(u);scan_d(v);scan_d(w); u--;v--; add(u,v,w,i); add(v,u,w,i); } dep[0] = 0; pre[0] = -1; bfs(0); scan_d(m); for(int i = 0; i < m; ++i){ int u,v; scan_d(u);scan_d(v); u--;v--; int p = lca(u,v); putint(dis[u] - dis[p] + dis[v] - dis[p]); puts(""); } return 0;}
tarjan离线:
#include<cstdio>#include<cstdlib>#include<iostream>#include<cstring>#include<map>#include<set>#include<list>#include<stack>#include<algorithm>#include<queue>#include<vector>#include<time.h>#include<iomanip>#include<assert.h>using namespace std;const int maxn = 100005;typedef long long ll;struct Edge{ int v; int next; int w; int id;}edge[maxn*4];int tot ;int first[maxn];int firstQuery[maxn];int father[maxn];int fa[maxn];int node[maxn][2];int dis[maxn];int lca[maxn];int find(int x){ return fa[x] = fa[x] == x? x:find(fa[x]);}void add(int uu,int vv,int ww){ edge[tot].v = vv; edge[tot].w = ww; edge[tot].next = first[uu]; first[uu] = tot++;}void addQuery(int u,int v){ edge[tot].v = v; edge[tot].next = firstQuery[u]; firstQuery[u] = tot++;}int n,m;inline bool scan_d(int &ret){ char c;int sgn; if(c = getchar(),c == EOF)return 0; while(c!='-' && (c<'0'||c>'9'))c = getchar(); sgn = (c == '-')?-1:1; ret = (c == '-')?0 :c-'0'; while(c = getchar(),c>='0'&&c<='9')ret = ret*10 + (c-'0'); ret *=sgn; return 1;}void putint(int x){ if(x<0){putchar('-'); x *= -1;} if(x == 0){ putchar('0'); return; } char s[20]; int cur = 0; while(x!=0){ s[cur++] = '0' + x%10; x/=10; } for(int i = cur-1;i>=0;i--){ putchar(s[i]); }}bool vis[maxn];void dfs(int u){ vis[u] = true; for(int e = first[u]; ~e; e = edge[e].next) { int v = edge[e].v; if (v == father[u]) continue; dis[v] = dis[u] + edge[e].w; father[v] = u; dfs(v); fa[find(v)] = find(u); } for(int e = firstQuery[u];~e ; e = edge[e].next) { int v = edge[e].v; int cnt = vis[node[v][0]] + vis[node[v][1]]; if (cnt == 2) { if (node[v][0] == u) { lca[v] = find(node[v][1]); } else { lca[v] = find(node[v][0]); } } }}void solve() { scan_d(n);scan_d(m); for(int i = 0; i < n; ++ i) { vis[i] = false; first[i] = -1; firstQuery[i] = -1; fa[i] = i; } tot = 0; int u, v,w; for(int i = 0; i < n - 1; ++ i) { scan_d(u); scan_d(v); scan_d(w); --u, --v; add(u, v, w); add(v, u, w); } scan_d(m); for(int i = 0; i < m; ++ i) { scan_d(node[i][0]);node[i][0] --; scan_d(node[i][1]);node[i][1] --; addQuery(node[i][0], i); addQuery(node[i][1], i); } father[0] = -1; tot = 0; dis[0] = 0; dfs(0); for(int i = 0; i < m; ++ i) { int u = node[i][0]; int v = node[i][1]; int p = lca[i]; printf("%d\n",dis[u] - dis[p] + dis[v] - dis[p]); }}int main() {// freopen("data.txt","r",stdin); solve(); return 0;}
0 0
- POJ 1986 — Distance Queries
- POJ 1986——Distance Queries
- poj 1986——Distance Queries
- POJ 1986 Distance Queries
- POJ 1986 Distance Queries
- poj 1986 Distance Queries
- POJ 1986 Distance Queries
- poj 1986 Distance Queries
- POJ-1986-Distance Queries
- poj 1986 Distance Queries
- POJ 1986 Distance Queries
- POJ 1986 Distance Queries
- poj——1986——Distance Queries
- (poj 1986 Distance Queries)<LCA—tarjan>
- POJ 1986 Distance Queries [LCA]
- poj 1986 Distance Queries LCA
- POJ 1986 Distance Queries(LCA)
- poj 1986 Distance Queries (LCA)
- iOS项目开发实战——使用用户首选项数据API存储信息
- 工厂模式
- 窗口缩小时图片、文字跟着整体缩小
- windows命令行安装Drupal7(包括drush安装与配置)
- PAT Basic level practice 03
- poj 1986——Distance Queries
- centos6.5下安装mysql,远程访问
- DLL 内部的非模态对话框的 PreTranslateMessage 函数不执行
- ruby 安装 gem 降级
- 工具分享 xml to json
- ORA-00942: 表或视图不存在 "的原因和解决方法
- 自动适应—根据分辨率大小可以相应显示不同图片(代码)
- SDK 更新配置
- NYOJ 6 喷水装置(一)