带权并查集 poj1984 Navigation Nightmare
思路是记录相对于父节点的偏移量
分别维护x和y即可
#第一个坑在读入既有数字又有字符的时候,要写成:
scanf("%d%d%d %c"),否则老锅。
#第二个坑是实现operation和查询的时候,处理p1和p2没写好,造成溢出了。
锅着,仍然re,待填ing。
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; const int maxn=5e5; int n,m,t,from[maxn],to[maxn],val[maxn],fa[maxn],x[maxn],y[maxn]; char dir[maxn]; struct node{ int f,t,id; }q[maxn]; bool cmp(node a,node b) { return a.id<b.id; } void pre( ) { for(int i=1;i<=maxn;i++) { fa[i]=i; x[i]=0; y[i]=0; } } int find(int i) { if(fa[i]!=i) { int tmp=fa[i]; fa[i]=find(fa[i]); x[i]=x[i]+x[tmp]; y[i]=y[i]+y[tmp]; } return fa[i]; } void unit(int i,int j,int val,char d) { //cout<<"yyds"<<d<<endl; int f1=find(j),f2=find(i); if(f1!=f2) { fa[f2]=f1; x[f2]=x[j]-x[i]; y[f2]=-y[i]+y[j]; if(d=='E') x[f2]-=val; if(d=='W') x[f2]+=val; if(d=='N') y[f2]-=val; if(d=='S') y[f2]+=val; } } void query(int i,int j) { int f1=find(i),f2=find(j); if(f1!=f2) { printf("-1\n"); return; } else { int ansx,ansy;; ansx=-x[i]+x[j]; ansx=abs(ansx); ansy=-y[i]+y[j]; ansy=abs(ansy); printf("%d\n",ansx+ansy); } } int main( ) { //freopen("lys.in","r",stdin); cin>>n>>m; pre( ); for(int i=1;i<=m;i++) { scanf("%d%d%d %c",&from[i],&to[i],&val[i],&dir[i]); } cin>>t; for(int i=1;i<=t;i++) { scanf("%d%d%d",&q[i].f,&q[i].t,&q[i].id); } sort(q+1,q+t+1,cmp); int j=1; for(int i=1;i<=t;i++) { for(;j<=q[i].id;j++) { unit(from[j],to[j],val[j],dir[j]); } query(q[i].f,q[i].t); } }