您的位置:首页 > 其它

poj 1984 Navigation Nightmare (带权并查集)

2019-02-18 09:45 309 查看

题解思路:

带权并查集只不过维护2个量;

在线查询十分恶心..

需要先把查询 和答案全记录下来,最后按pos输出;

[code]#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\n",out[i].ans);
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: