题解思路:
带权并查集只不过维护2个量;
在线查询十分恶心..
需要先把查询 和答案全记录下来,最后按pos输出;
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<set> #include<map> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define ll long long const int maxn=1e5+10; using namespace std; int f[maxn],sumx[maxn],sumy[maxn]; struct A{ int ans,pos; }out[maxn]; struct node{ int x,y,v,pos; bool operator < (const node &cmp) const{ return v>cmp.v; } }; struct data{ int a,b,v; char ch; }arr[maxn]; int root(int x) { if(f[x]==x) return x; int rt=root(f[x]); sumx[x]+=sumx[f[x]]; sumy[x]+=sumy[f[x]]; return f[x]=rt; } int cmp(A a,A b) { return a.pos<b.pos; } void init() { mem(sumx,0); mem(sumy,0); } void cul(int a,int b,int w,char ch) { int x=root(a),y=root(b); if(x!=y) { f[x]=y; if(ch=='E') { sumx[x]=sumx[b]+w-sumx[a]; sumy[x]=sumy[b]-sumy[a]; } if(ch=='W') { sumx[x]=sumx[b]-w-sumx[a]; sumy[x]=sumy[b]-sumy[a]; } if(ch=='N') { sumy[x]=sumy[b]+w-sumy[a]; sumx[x]=sumx[b]-sumx[a]; } if(ch=='S') { sumy[x]=sumy[b]-w-sumy[a]; sumx[x]=sumx[b]-sumx[a]; } } } int main(){ int n,m,k; scanf("%d%d",&n,&m); init(); for(int i=1;i<=n;i++) f[i]=i; int a,b,v; char ch; for(int i=1;i<=m;i++) { scanf("%d%d%d %c",&a,&b,&v,&ch); arr[i]=(data){a,b,v,ch}; } scanf("%d",&k); priority_queue<node>q; for(int i=1;i<=k;i++) { scanf("%d%d%d",&a,&b,&v); q.push((node){a,b,v,i}); } int j=1; for(int i=1;i<=k;i++) { for(;j<=q.top().v;j++) cul(arr[j].a,arr[j].b,arr[j].v,arr[j].ch); int x=q.top().x; int y=q.top().y; int ans=-1; a=root(x); b=root(y); if(a==b) { ans=abs(sumx[x]-sumx[y])+abs(sumy[x]-sumy[y]); } out[i]=(A){ans,q.top().pos}; q.pop(); } sort(out+1,out+1+k,cmp); for(int i=1;i<=k;i++) { printf("%d ",out[i].ans); } return 0; }