首页 > 代码库 > POJ 1984 Navigation Nightmare 二维带权并查集
POJ 1984 Navigation Nightmare 二维带权并查集
题目来源:POJ 1984 Navigation Nightmare
题意:给你一颗树 k次询问 求2点之间的曼哈顿距离 并且要在只有开始k条边的情况下
思路:按照方向 我是以左上角为根 左上角为原点 dx[i]为i点距离根的x坐标 dy[]是y坐标 这两个可以通过路径压缩求出 只不过是二维而已
#include <cstdio> #include <cstdlib> #include <cstring> using namespace std; const int maxn = 40010; int f[maxn], dx[maxn], dy[maxn]; struct node { int u, v, w; char s[3]; }a[maxn]; void init(int n) { for(int i = 1; i <= n; i++) f[i] = i; memset(dx, 0, sizeof(dx)); memset(dy, 0, sizeof(dy)); } int find(int x) { if(x != f[x]) { int rt = find(f[x]); dx[x] += dx[f[x]]; dy[x] += dy[f[x]]; f[x] = rt; return rt; } return x; } int main() { int n, m; scanf("%d %d", &n, &m); init(n); for(int i = 1; i <= m; i++) { scanf("%d %d %d %s", &a[i].u, &a[i].v, &a[i].w, a[i].s); } int q; scanf("%d", &q); int i = 1; while(q--) { int s, e, w; scanf("%d %d %d", &s, &e, &w); while(i <= m && i <= w) { int u = a[i].u; int v = a[i].v; int x = find(u); int y = find(v); if(x == y) continue; if(a[i].s[0] == 'E') { f[y] = x; dx[y] = dx[u]-dx[v]+a[i].w; dy[y] = dy[u]-dy[v]; } else if(a[i].s[0] == 'W') { f[x] = y; dx[x] = dx[v]-dx[u]+a[i].w; dy[x] = dy[v]-dy[u]; } else if(a[i].s[0] == 'N') { f[x] = y; dy[x] = dy[v]-dy[u]+a[i].w; dx[x] = dx[v]-dx[u]; } else { f[y] = x; dy[y] = dy[u]-dy[v]+a[i].w; dx[y] = dx[u]-dx[v]; } i++; } int x = find(s); int y = find(e); if(x == y) { int d = abs(dx[s]-dx[e]) + abs(dy[s]-dy[e]); printf("%d\n", d); } else { puts("-1"); } } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。