POJ 1984 Navigation Nightmare
并查集,给n个点和m条边,每条边有方向和长度,再给q个询问,第i个询问查询两个点之间在Ti时刻时的曼哈顿距离(能连通则输出曼哈顿距离,否则输出-1)
这题跟Corporative Network 有点像,只不过那题是维护到根节点的距离,这题还要顺便维护与根节点的x,y方向的偏移量。findset时,每次找完father就要加上father的x、y坐标偏移量,这样findset完以后就得到了与根的偏移量。然后合并时, (注意,这里是 fa[x] = y)
dr[x].x = r.x - dr[r.u].x + dr[r.v].x;
dr[x].y = r.y - dr[r.u].y + dr[r.v].y; 即 x->y <==> u->v - u->x + v->y 如下图:
这题还要注意数据可能不是按照时间顺序输入的,要做一个排序,然后再按原来的顺序输出。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 40100 int fa[N],q; struct DR { int x,y; }dr[N],to[27]; struct ROAD { int u,v; int x,y; }road[N]; struct QUERY { int a,b,time; int id,res; }query[N]; void makeset(int n) { for(int i=1;i<=n;i++) { fa[i] = i; dr[i].x = dr[i].y = 0; } } int findset(int x) { if(x != fa[x]) { int tmp = fa[x]; fa[x] = findset(fa[x]); dr[x].x += dr[tmp].x; dr[x].y += dr[tmp].y; } return fa[x]; } void unionset(int index) //合并第index条边 { ROAD r = road[index]; int x = findset(r.u); int y = findset(r.v); if(x == y) return; fa[x] = y; dr[x].x = r.x - dr[r.u].x + dr[r.v].x; // x->y <==> u->v - u->x + v->y dr[x].y = r.y - dr[r.u].y + dr[r.v].y; } int cmp1(QUERY ka,QUERY kb) { return ka.time<kb.time; } int cmp2(QUERY ka,QUERY kb) { return ka.id<kb.id; } void InitDirection() { to['E'-'A'].x = 1; to['E'-'A'].y = 0; to['W'-'A'].x = -1; to['W'-'A'].y = 0; to['N'-'A'].x = 0; to['N'-'A'].y = 1; to['S'-'A'].x = 0; to['S'-'A'].y = -1; } void read() { int n,m,i,dis; char ss[4]; InitDirection(); scanf("%d%d",&n,&m); makeset(n); for(i=1;i<=m;i++) { scanf("%d%d%d %s",&road[i].u,&road[i].v,&dis,ss); road[i].x = dis*(to[ss[0]-'A'].x); road[i].y = dis*(to[ss[0]-'A'].y); } scanf("%d",&q); for(i=1;i<=q;i++) { scanf("%d%d%d",&query[i].a,&query[i].b,&query[i].time); query[i].id = i; } sort(query+1,query+q+1,cmp1); } void solve() { int i,j; j=1; for(i=1;i<=q;i++) { for(;j<=query[i].time;j++) { unionset(j); } if(findset(query[i].a) != findset(query[i].b)) query[i].res = -1; else query[i].res = abs(dr[query[i].a].x-dr[query[i].b].x) + abs(dr[query[i].a].y-dr[query[i].b].y); } sort(query+1,query+q+1,cmp2); for(i=1;i<=q;i++) cout<<query[i].res<<endl; } int main() { read(); solve(); return 0; }
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com