poj 1984 Navigation Nightmare (带权并查集)

题解思路:

带权并查集只不过维护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;
}


原文地址:https://www.cnblogs.com/minun/p/10473765.html