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; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。