题目链接:http://poj.org/problem?id=1984
给定n个城市,m条边告诉你城市间的相对距离,接下来q组询问,问你在第几条边添加后两城市的距离。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <stack> #include <map> #include <vector> using namespace std; typedef long long LL; #define PI 4*atan(1.0) #define N 42000 #define met(a, b) memset(a, b, sizeof(a)) int f[N], rx[N], ry[N], ans[N]; ///rx[i]表示i和f[i]的x的偏移量,ry[i]是y的偏移量; struct node { int u, v, d, I, Id; char dir[10]; }a[N], q[N]; int cmp(node p, node q) { return p.Id<q.Id; } int Find(int x) { int k = f[x]; if(x!=f[x]) { f[x] = Find(f[x]); rx[x] += rx[k]; ry[x] += ry[k]; } return f[x]; } void Union(int num) { int x = a[num].u, y = a[num].v; char ch = a[num].dir[0]; int px = Find(x), py = Find(y); if(px != py) { f[px] = py; rx[px] = rx[y] - rx[x]; ry[px] = ry[y] - ry[x]; if(ch == ‘E‘) rx[px] -= a[num].d ; if(ch == ‘W‘) rx[px] += a[num].d; if(ch == ‘N‘) ry[px] -= a[num].d; if(ch == ‘S‘) ry[px] += a[num].d; } } int main() { int n, m, Q; while(scanf("%d %d", &n, &m)!=EOF) { met(a, 0);met(q, 0); met(ans, 0); for(int i=0; i<=n; i++) f[i] = i, rx[i] = ry[i] = 0; for(int i=1; i<=m; i++) scanf("%d %d %d %s", &a[i].u, &a[i].v, &a[i].d, a[i].dir); scanf("%d", &Q); for(int i=1; i<=Q; i++) { scanf("%d %d %d", &q[i].u, &q[i].v, &q[i].I); q[i].Id = i; } sort(q+1, q+Q+1, cmp);///不排序也可以;因为是按I的顺序给的; for(int pre=0, i=1; i<=Q; i++) { for(int j=pre+1; j<=q[i].I; j++) Union(j); pre = q[i].I; int u = q[i].u, v = q[i].v; int px = Find(u); int py = Find(v); if(px != py) ans[q[i].Id] = -1; else ans[q[i].Id] = abs(rx[u]-rx[v]) + abs(ry[u]-ry[v]); } for(int i=1; i<=Q; i++) printf("%d\n", ans[i]); } return 0; }
Navigation Nightmare---poj1984(多关系并查集)
原文:http://www.cnblogs.com/zhengguiping--9876/p/5483254.html